SafeInt 類別
擴充的整數基本型別,以協助防止整數的溢位,可讓您比較不同類型的整數。
template<typename T, typename E = _SAFEINT_DEFAULT_ERROR_POLICY>
class SafeInt;
參數
範本 |
描述 |
---|---|
T |
整數或布林值參數的型別, SafeInt會取代。 |
E |
列舉的資料型別定義的錯誤處理原則。 |
U |
整數或布林值參數,第二個運算元的型別。 |
參數 |
描述 |
---|---|
[in] 在 rhs |
輸入的參數,表示在數個獨立的函式中的運算子右邊的值。 |
[in 我 |
輸入的參數,表示在數個獨立的函式中的運算子右邊的值。 |
[in] 在位元 |
輸入的參數,表示在數個獨立的函式中的運算子右邊的值。 |
Members
公用建構函式
名稱 |
描述 |
---|---|
預設建構函式。 |
指派運算子
名稱 |
語法 |
---|---|
= |
template<typename U> SafeInt<T,E>& operator= (const U& rhs) |
= |
SafeInt<T,E>& operator= (const T& rhs) throw() |
= |
template<typename U> SafeInt<T,E>& operator= (const SafeInt<U, E>& rhs) |
= |
SafeInt<T,E>& operator= (const SafeInt<T,E>& rhs) throw() |
轉型運算子
名稱 |
語法 |
---|---|
bool |
operator bool() throw() |
char |
operator char() const |
signed char |
operator signed char() const |
unsigned char |
operator unsigned char() const |
__int16 |
operator __int16() const |
unsigned __int16 |
operator unsigned __int16() const |
__int32 |
operator __int32() const |
unsigned __int32 |
operator unsigned __int32() const |
long |
operator long() const |
unsigned long |
operator unsigned long() const |
__int64 |
operator __int64() const |
unsigned __int64 |
operator unsigned __int64() const |
wchar_t |
operator wchar_t() const |
比較運算子
名稱 |
語法 |
---|---|
< |
template<typename U> bool operator< (U rhs) const throw() |
< |
bool operator< (SafeInt<T,E> rhs) const throw() |
>= |
template<typename U> bool operator>= (U rhs) const throw() |
>= |
Bool operator>= (SafeInt<T,E> rhs) const throw() |
> |
template<typename U> bool operator> (U rhs) const throw() |
> |
Bool operator> (SafeInt<T,E> rhs) const throw() |
<= |
template<typename U> bool operator<= (U rhs) const throw() |
<= |
bool operator<= (SafeInt<T,E> rhs) const throw() |
== |
template<typename U> bool operator== (U rhs) const throw() |
== |
bool operator== (bool rhs) const throw() |
== |
bool operator== (SafeInt<T,E> rhs) const throw() |
!= |
template<typename U> bool operator!= (U rhs) const throw() |
!= |
bool operator!= (bool b) const throw() |
!= |
bool operator!= (SafeInt<T,E> rhs) const throw() |
算術運算子
名稱 |
語法 |
---|---|
+ |
const SafeInt<T,E>& operator+ () const throw() |
- |
SafeInt<T,E> operator- () const |
++ |
SafeInt<T,E>& operator++ () |
-- |
SafeInt<T,E>& operator-- () |
% |
template<typename U> SafeInt<T,E> operator% (U rhs) const |
% |
SafeInt<T,E> operator% (SafeInt<T,E> rhs) const |
%= |
template<typename U> SafeInt<T,E>& operator%= (U rhs) |
%= |
template<typename U> SafeInt<T,E>& operator%= (SafeInt<U, E> rhs) |
* |
template<typename U> SafeInt<T,E> operator* (U rhs) const |
* |
SafeInt<T,E> operator* (SafeInt<T,E> rhs) const |
*= |
SafeInt<T,E>& operator*= (SafeInt<T,E> rhs) |
*= |
template<typename U> SafeInt<T,E>& operator*= (U rhs) |
*= |
template<typename U> SafeInt<T,E>& operator*= (SafeInt<U, E> rhs) |
/ |
template<typename U> SafeInt<T,E> operator/ (U rhs) const |
/ |
SafeInt<T,E> operator/ (SafeInt<T,E> rhs ) const |
/= |
SafeInt<T,E>& operator/= (SafeInt<T,E> i) |
/= |
template<typename U> SafeInt<T,E>& operator/= (U i) |
/= |
template<typename U> SafeInt<T,E>& operator/= (SafeInt<U, E> i) |
+ |
SafeInt<T,E> operator+ (SafeInt<T,E> rhs) const |
+ |
template<typename U> SafeInt<T,E> operator+ (U rhs) const |
+= |
SafeInt<T,E>& operator+= (SafeInt<T,E> rhs) |
+= |
template<typename U> SafeInt<T,E>& operator+= (U rhs) |
+= |
template<typename U> SafeInt<T,E>& operator+= (SafeInt<U, E> rhs) |
- |
template<typename U> SafeInt<T,E> operator- (U rhs) const |
- |
SafeInt<T,E> operator- (SafeInt<T,E> rhs) const |
-= |
SafeInt<T,E>& operator-= (SafeInt<T,E> rhs) |
-= |
template<typename U> SafeInt<T,E>& operator-= (U rhs) |
-= |
template<typename U> SafeInt<T,E>& operator-= (SafeInt<U, E> rhs) |
邏輯運算子
名稱 |
語法 |
---|---|
! |
bool operator !() const throw() |
~ |
SafeInt<T,E> operator~ () const throw() |
<< |
template<typename U> SafeInt<T,E> operator<< (U bits) const throw() |
<< |
template<typename U> SafeInt<T,E> operator<< (SafeInt<U, E> bits) const throw() |
<<= |
template<typename U> SafeInt<T,E>& operator<<= (U bits) throw() |
<<= |
template<typename U> SafeInt<T,E>& operator<<= (SafeInt<U, E> bits) throw() |
>> |
template<typename U> SafeInt<T,E> operator>> (U bits) const throw() |
>> |
template<typename U> SafeInt<T,E> operator>> (SafeInt<U, E> bits) const throw() |
>>= |
template<typename U> SafeInt<T,E>& operator>>= (U bits) throw() |
>>= |
template<typename U> SafeInt<T,E>& operator>>= (SafeInt<U, E> bits) throw() |
& |
SafeInt<T,E> operator& (SafeInt<T,E> rhs) const throw() |
& |
template<typename U> SafeInt<T,E> operator& (U rhs) const throw() |
&= |
SafeInt<T,E>& operator&= (SafeInt<T,E> rhs) throw() |
&= |
template<typename U> SafeInt<T,E>& operator&= (U rhs) throw() |
&= |
template<typename U> SafeInt<T,E>& operator&= (SafeInt<U, E> rhs) throw() |
^ |
SafeInt<T,E> operator^ (SafeInt<T,E> rhs) const throw() |
^ |
template<typename U> SafeInt<T,E> operator^ (U rhs) const throw() |
^= |
SafeInt<T,E>& operator^= (SafeInt<T,E> rhs) throw() |
^= |
template<typename U> SafeInt<T,E>& operator^= (U rhs) throw() |
^= |
template<typename U> SafeInt<T,E>& operator^= (SafeInt<U, E> rhs) throw() |
| |
SafeInt<T,E> operator| (SafeInt<T,E> rhs) const throw() |
| |
template<typename U> SafeInt<T,E> operator| (U rhs) const throw() |
|= |
SafeInt<T,E>& operator|= (SafeInt<T,E> rhs) throw() |
|= |
template<typename U> SafeInt<T,E>& operator|= (U rhs) throw() |
|= |
template<typename U> SafeInt<T,E>& operator|= (SafeInt<U, E> rhs) throw() |
備註
SafeInt類別會防止整數的溢位算術運算中。比方說,請考慮加入兩個 8 位元整數: 其中一項具有 200 的值,且第二個值為 100。正確的數學運算會是200 + 100 = 300。不過,因為 8 位元整數限制的較高的位元將會遺失,並且編譯器將會傳回 44 (300-28) 的結果。這個數學方程式所依賴的任何作業將會產生無法預期的行為。
SafeInt的類別便檢查是否發生算術溢位或程式碼是否會嘗試除數為零。在這兩種情況下,類別會呼叫錯誤處理常式,以警告潛在問題的程式。
這個類別也可讓您比較兩個不同類型的整數,因為它們是SafeInt物件。一般而言,當您執行比較時,您必須先將轉換的數字是相同的型別。將轉型為另一種類型的一個數字通常需要檢查並確認沒有流失資料。
本主題中的運算子表格列出的算術和比較運算子支援的SafeInt類別。最數學運算子會傳回SafeInt型別的物件T。
之間的比較作業SafeInt和可執行任一方向的整數型別。比方說,兩者都SafeInt<int>(x) < y和y > SafeInt<int>(x)有效,並且會傳回相同的結果。
許多的二元運算子不支援使用兩個不同, SafeInt型別。一個例子,它是**&**運算子。SafeInt<T, E> & int有支援,但SafeInt<T, E> & SafeInt<U, E>不是。在第二個範例中,編譯器不知道何種類型的參數傳回。將第二個參數,傳回給基底型別轉換為有一個解決這個問題。藉由使用相同的參數,這可以使用SafeInt<T, E> & (U)SafeInt<U, E>。
![]() |
---|
任何位元運算,兩個不同的參數應該是相同的大小。如果大小不同,編譯器就會擲回ASSERT (MFC)例外狀況。無法保證這項作業的結果,以使其精確。如果要解決這個問題,請將較小的參數轉換較大的參數相同的大小為止。 |
移位運算子,移位超過現有範本類型,更多位元將會擲回例外狀況的判斷提示。在發行模式裡,這會有任何作用。混用了兩種類型的 SafeInt 參數有可能移位運算子,因為傳回型別是原始型別相同。運算子的右邊顯示數目只表示要移位的位元數。
當您執行與 SafeInt 物件的邏輯比較時,則這個比較是嚴格算術。比方說,請參考下列運算式:
SafeInt<uint>((uint)~0) > -1
((uint)~0) > -1
第一個陳述式會解析成true,但第二個陳述式會解析成false。0 的位元否定是 0xFFFFFFFF。在第二個陳述式,則預設的比較運算子比較 0xFFFFFFFF 0xffffffff 之間,並且會考慮它們才會相等。比較運算子的SafeInt類別解析第二個參數是負的而第一個參數是不帶正負號。因此,位元表示是相同的不過,當SafeInt的邏輯運算子會實現的不帶正負號的整數是較大的值為-1。
當您使用時要小心SafeInt類別一起**?:**三元運算子。請考慮下列程式碼行。
Int x = flag ? SafeInt<unsigned int>(y) : -1;
編譯器會將它轉換成這樣:
Int x = flag ? SafeInt<unsigned int>(y) : SafeInt<unsigned int>(-1);
如果flag是false,編譯器就會擲回例外狀況,而不是將值指派為-1 到x。因此,若要避免這個問題,請使用正確的程式碼是下面這一行。
Int x = flag ? (int) SafeInt<unsigned int>(y) : -1;
T與U布林型別、 字元型別或整數型別來指派。型別可以是帶正負號或不帶正負號的整數,任何為 64 位元 8 位元的大小。
![]() |
---|
雖然SafeInt類別會接受任何一種整數之後,會更有效率地使用不帶正負號的型別。 |
E是錯誤的處理機制, SafeInt會使用。這兩個錯誤處理機制提供了 SafeInt 程式庫。預設的原則是SafeIntErrorPolicy_SafeIntException,哪一個擲回SafeIntException 類別發生錯誤時的例外狀況。其他的原則是SafeIntErrorPolicy_InvalidParameter,它會停止程式,如果發生錯誤。
有兩個選項來自訂錯誤的原則。若要將參數設定的第一個選項是E當您建立SafeInt。使用此選項,當您想要變更的錯誤處理原則是只有一個SafeInt。另一個選擇是要定義**_SAFEINT_DEFAULT_ERROR_POLICY成為您的自訂的錯誤處理類別,才能加入SafeInt程式庫。使用此選項,當您想要變更預設的錯誤處理原則的所有出現處SafeInt**在程式碼中的類別。
![]() |
---|
自訂的類別,以處理從 SafeInt 程式庫錯誤應該傳回給呼叫的錯誤處理常式的程式碼的控制項。錯誤處理常式呼叫時,結果之後, SafeInt作業不能信任。 |
需求
標頭: safeint.h
Namespace: msl::utilities