Condividi tramite


Classe SafeInt

Estende le primitive Integer per impedire un overflow di Integer e consente di confrontare tipi diversi di Integer.

template<typename T, typename E = _SAFEINT_DEFAULT_ERROR_POLICY>
class SafeInt;

Parametri

Modello

Descrizione

T

Il tipo di parametro Integer o booleano che SafeInt sostituisce.

E

Un tipo di dati enumerato che definisce i criteri di gestione degli errori.

U

Il tipo di parametro Integer o booleano per l'operando secondario.

Parametro

Descrizione

[in] rhs

Un parametro di input che rappresenta il valore a destra dell'operatore in diverse funzioni autonome.

[in] i

Un parametro di input che rappresenta il valore a destra dell'operatore in diverse funzioni autonome.

[in] bit

Un parametro di input che rappresenta il valore a destra dell'operatore in diverse funzioni autonome.

Membri

Dd570021.collapse_all(it-it,VS.110).gifCostruttori pubblici

Nome

Descrizione

SafeInt::SafeInt

Costruttore predefinito.

Dd570021.collapse_all(it-it,VS.110).gifOperatori di assegnazione

Nome

Sintassi

=

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()

Dd570021.collapse_all(it-it,VS.110).gifOperatori di cast

Nome

Sintassi

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

Dd570021.collapse_all(it-it,VS.110).gifOperatori di confronto

Nome

Sintassi

<

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()

Dd570021.collapse_all(it-it,VS.110).gifOperatori aritmetici

Nome

Sintassi

+

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)

Dd570021.collapse_all(it-it,VS.110).gifOperatori logici

Nome

Sintassi

!

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()

Note

La classe di SafeInt protegge dall'overflow di Integer nelle operazioni matematiche.Ad esempio, considerare la possibilità di aggiungere due Integer a 8 bit: uno con un valore di 200 e il secondo è un valore di 100.Un'operazione matematica corretta sarebbe 200 + 100 = 300.Tuttavia, a causa del limite Integer a 8 bit, il bit superiore andrà perduto e il compilatore restituirà 44 (da 300 a 28) del risultato.Qualsiasi operazione che dipende da questa equazione matematica genererà un comportamento imprevisto.

La classe di SafeInt controlla se un overflow si verifichi o se il codice tenta di dividere per zero.In entrambi i casi, la classe chiama il gestore degli errori per avvisare il programma del potenziale problema.

Questa classe consente di confrontare due tipi diversi di Integer purché siano oggetti di SafeInt .In genere, quando si esegue un confronto, è necessario innanzitutto convertire numeri dello stesso tipo.Eseguire il cast di un numero in un altro tipo richiede spesso i controlli di assicurarsi che non vengano perdita di dati.

Il piano degli operatori in questo argomento vengono elencati i matematico e gli operatori di confronto supportati da SafeInt la classe.La maggior parte degli operatori matematici restituiscono un oggetto di SafeInt di tipo T.

Le operazioni di confronto tra SafeInt e un tipo integrale possono essere eseguite in entrambe le direzioni.Ad esempio, sia SafeInt<int>(x) < y che y > SafeInt<int>(x) sono validi e restituiscono lo stesso risultato.

Molti operatori binari non supportano l'utilizzo di due tipi diversi di SafeInt .Un esempio è l'operatore di & .SafeInt<T, E> & int è supportato, ma SafeInt<T, E> & SafeInt<U, E> non è.Nell'esempio precedente, il compilatore non riconosce il tipo di parametro da restituire.Una soluzione a questo problema consiste nell'eseguire il cast del secondo parametro del tipo di base.Utilizzando gli stessi parametri, questa operazione può essere eseguita con SafeInt<T, E> & (U)SafeInt<U, E>.

[!NOTA]

Per tutte le operazioni bit per bit, i due parametri diversi devono essere la stessa dimensione.Se le dimensioni sono diversi, il compilatore genererà un'eccezione di ASSERT (MFC) .I risultati di questa operazione non possono essere garantiti per essere precisi.Per risolvere questo problema, eseguire il cast del più piccolo parametro che sia la stessa dimensione del più ampio parametro.

Per gli operatori di spostamento, scorrendo più bit che esistere per il tipo di modello genera un'eccezione ASSERT.Ciò non avrà alcun effetto in modalità di rilascio.Combinare due tipi di parametri SafeInt è possibile che gli operatori di spostamento poiché il tipo restituito corrisponde al tipo originale.Il numero sul lato destro dell'operatore indica solo il numero di bit allo spostamento.

Quando si esegue un confronto logico con un oggetto SafeInt, il confronto è strettamente aritmetico.Ad esempio, considerare queste espressioni:

  • SafeInt<uint>((uint)~0) > -1

  • ((uint)~0) > -1

Le prime risoluzioni di istruzione a true, mentre nel secondo viene risolto in un'istruzione a false.La negazione bit per bit di 0 è 0xFFFFFFFF.Nella seconda istruzione, l'operatore di confronto predefinito confronta 0xFFFFFFFF a 0xFFFFFFFF e vengono considerate uguali.L'operatore di confronto per la classe di SafeInt tenere presente che il secondo parametro è negativo come primo parametro è senza segno.Pertanto, sebbene la rappresentazione di bit saranno identiche, l'operatore logico di SafeInt tenere presente che l'Unsigned Integer è maggiore di -1.

Prestare attenzione quando si utilizza la classe di SafeInt con l'operatore ternario di ?: .Si consideri la seguente riga di codice.

Int x = flag ? SafeInt<unsigned int>(y) : -1;

Il compilatore viene convertito alla seguente:

Int x = flag ? SafeInt<unsigned int>(y) : SafeInt<unsigned int>(-1);

Se flag è false, il compilatore genera un'eccezione anziché assegnare il valore -1 a x.Di conseguenza, evitare questo comportamento, il codice corretto per utilizzare è la seguente riga.

Int x = flag ? (int) SafeInt<unsigned int>(y) : -1;

T e U è possibile assegnare un tipo boolean, il tipo di carattere, o il tipo integer.Tipi integer possono essere firmati con o senza segno e qualsiasi dimensione di 8 bit a 64 bit.

[!NOTA]

Sebbene la classe di SafeInt accetta qualsiasi tipo di Integer, esegue più efficiente dei tipi senza segno.

E è il meccanismo di gestione degli errori che SafeInt utilizza.Due meccanismi di gestione degli errori vengono forniti della libreria SafeInt.I criteri predefiniti sono SafeIntErrorPolicy_SafeIntException, che generano un'eccezione di Classe SafeIntException quando si verifica un errore.Gli altri criteri vengono SafeIntErrorPolicy_InvalidParameter, che interrompono il programma se si verifica un errore.

Sono disponibili due opzioni per la personalizzazione dei criteri di errore.La prima opzione consiste di impostare il parametro E quando si crea SafeInt.Utilizzare questa opzione quando si desidera modificare i criteri di gestione degli errori per un solo SafeInt.Un'altra opzione consiste nel definire _SAFEINT_DEFAULT_ERROR_POLICY per essere la classe personalizzata di gestione degli errori prima di importare la libreria di SafeInt .Utilizzare questa opzione quando si desidera modificare i criteri predefiniti di gestione degli errori per tutte le istanze della classe di SafeInt nel codice.

[!NOTA]

Una classe personalizzata che gestisce gli errori dalla libreria SafeInt non deve restituire il controllo del codice che ha chiamato il gestore errori.Dopo che il gestore degli errori viene chiamato, il risultato dell'operazione di SafeInt non può essere attendibile.

Requisiti

intestazione: safeint.h

Msl::utilities diSpazio dei nomi:

Vedere anche

Riferimenti

Classe SafeIntException

Altre risorse

Varie classi delle librerie di supporto

Libreria SafeInt