Classe SafeInt
Estende os primitivos inteiro para ajudar a impedir o estouro de inteiros e permite comparar diferentes tipos de números inteiros.
template<typename T, typename E = _SAFEINT_DEFAULT_ERROR_POLICY>
class SafeInt;
Parâmetros
Modelo |
Descrição |
---|---|
T |
O tipo de parâmetro booleano ou inteiro que SafeInt substitui. |
E |
Tipo de dados enumerado que define a política de manipulação de erros. |
U |
O tipo de inteiro ou parâmetro booleano operando secundário. |
Parâmetro |
Descrição |
---|---|
[rhs in] |
Um parâmetro de entrada que representa o valor no lado direito do operador em várias funções autônomas. |
[in] eu |
Um parâmetro de entrada que representa o valor no lado direito do operador em várias funções autônomas. |
[bits in] |
Um parâmetro de entrada que representa o valor no lado direito do operador em várias funções autônomas. |
Membros
Construtores públicos
Nome |
Descrição |
---|---|
Construtor padrão. |
Operadores de Atribuição
Nome |
Sintaxe |
---|---|
= |
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() |
Operadores de conversão
Nome |
Sintaxe |
---|---|
bool |
operator bool() throw() |
char |
operator char() const |
signed char |
operator signed char() const |
unsigned char |
operator unsigned char() const |
__int16 |
operator __int16() const |
__int16 não assinados |
operator unsigned __int16() const |
__int32 |
operator __int32() const |
__int32 não assinados |
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 |
Operadores de Comparação
Nome |
Sintaxe |
---|---|
< |
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() |
Operadores aritméticos
Nome |
Sintaxe |
---|---|
+ |
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) |
Operadores lógicos
Nome |
Sintaxe |
---|---|
! |
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() |
Comentários
O SafeInt classe oferece proteção contra estouro de inteiros em operações matemáticas.Por exemplo, considere a adição de dois inteiros de 8 bits: um tem um valor de 200 e o segundo tem um valor de 100.A operação matemática correta seria 200 + 100 = 300.No entanto, por causa do limite de inteiro de 8 bits, o bit superior serão perdido e o compilador irá retornar 44 (2 3008) como resultado.Qualquer operação que depende esta equação matemática irá gerar um comportamento inesperado.
O SafeInt classe verifica se ocorre um estouro aritmético ou se o código tentar dividir por zero.Em ambos os casos, a classe chama o manipulador de erro para avisar o programa do problema potencial.
Essa classe também permite que você compare dois tipos diferentes de inteiros como eles são SafeInt objetos.Normalmente, quando você executa uma comparação, deve primeiro converter os números para ser do mesmo tipo.Projeção freqüentemente um número para outro tipo requer verificações para certificar-se de que não há nenhuma perda de dados.
A tabela de operadores neste tópico lista os operadores matemáticos e comparação com suporte a SafeInt classe.Operadores matemáticos mais retornam um SafeInt objeto do tipo T.
Operações de comparação entre um SafeInt e tipo integral pode ser realizado em qualquer direção.Por exemplo, SafeInt<int>(x) < y e y > SafeInt<int>(x) são válidos e retornará o mesmo resultado.
Muitos operadores binários não oferecem suporte a diferentes SafeInt tipos.Um exemplo é o & operador.SafeInt<T, E> & inté suportado, mas SafeInt<T, E> & SafeInt<U, E> não é.No último exemplo, o compilador não sabe que tipo de parâmetro para retornar.Uma solução para esse problema é converter o segundo parâmetro para o tipo base.Usando os mesmos parâmetros, isso pode ser feito com SafeInt<T, E> & (U)SafeInt<U, E>.
Observação |
---|
Para qualquer operação bit a bit, os dois parâmetros diferentes devem ser do mesmo tamanho.Se os tamanhos forem diferentes, o compilador emitirá um ASSERT (MFC) exceção.Os resultados dessa operação não podem ser garantidos para ser preciso.Para resolver esse problema, converta o parâmetro menor até que ele é do mesmo tamanho que o parâmetro maior. |
Para os operadores de deslocamento, deslocar mais bits que existe para o tipo de modelo lançará uma exceção ASSERT.Isso não terá nenhum efeito no modo de versão.Mistura de dois tipos de parâmetros de SafeInt é possível para os operadores de deslocamento porque o tipo de retorno é o mesmo que o tipo original.O número à direita do operador somente indica o número de bits shift.
Quando você executa uma comparação lógica com um objeto SafeInt, a comparação é estritamente aritmética.Por exemplo, considere estas expressões:
SafeInt<uint>((uint)~0) > -1
((uint)~0) > -1
Resolve a primeira instrução em true, mas a segunda instrução resolve para false.Negação bit a bit 0 é 0xFFFFFFFF.Na segunda instrução, o operador de comparação padrão compara 0xFFFFFFFF para 0xFFFFFFFF e considera igual.O operador de comparação para o SafeInt classe percebe que o segundo parâmetro é negativo, enquanto o primeiro parâmetro não está assinado.Portanto, embora a representação de bit é idêntica, o SafeInt operador lógico percebe inteiro não assinado é maior que -1.
Tenha cuidado ao usar o SafeInt classe junto com o ?: operador Ternário.Considere a seguinte linha de código.
Int x = flag ? SafeInt<unsigned int>(y) : -1;
O compilador converte para isso:
Int x = flag ? SafeInt<unsigned int>(y) : SafeInt<unsigned int>(-1);
Se flag é false, o compilador lança uma exceção em vez de atribuir o valor de -1 a x.Portanto, para evitar esse comportamento, o código correto para usar é a linha a seguir.
Int x = flag ? (int) SafeInt<unsigned int>(y) : -1;
Te U pode ser atribuído um tipo booleano, tipo de caractere ou tipo inteiro.Inteiro tipos podem ser assinados ou não assinados e qualquer tamanho de 8 bits para 64 bits.
Observação |
---|
Embora o SafeInt classe aceita qualquer tipo de número inteiro, ele executa com mais eficiência com tipos não assinados. |
Eé o mecanismo de manipulação de erros que SafeInt usa.Dois mecanismos de manipulação de erro são fornecidos com a biblioteca SafeInt.A diretiva padrão é SafeIntErrorPolicy_SafeIntException, que lança um Classe SafeIntException quando ocorre um erro de exceção.A outra diretiva é SafeIntErrorPolicy_InvalidParameter, que interrompe o programa se ocorrer um erro.
Há duas opções para personalizar a diretiva de erro.A primeira opção é definir o parâmetro E quando você cria um SafeInt.Use esta opção quando você deseja alterar para apenas uma política de manipulação de erros SafeInt.Outra opção é definir _SAFEINT_DEFAULT_ERROR_POLICY para sua classe de tratamento de erros personalizado antes de incluir o SafeInt biblioteca.Use esta opção quando desejar alterar o diretiva para todas as instâncias de tratamento de erros padrão do SafeInt classe em seu código.
Observação |
---|
Uma classe personalizada que manipula os erros da biblioteca de SafeInt não deve retornar controle para o código que chamou o manipulador de erro.Depois que o manipulador de erro é chamado, o resultado do SafeInt operação não pode ser confiável. |
Requisitos
Cabeçalho: safeint.h
Namespace: msl::utilities