Partilhar via


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

Dd570021.collapse_all(pt-br,VS.110).gifConstrutores públicos

Nome

Descrição

SafeInt::SafeInt

Construtor padrão.

Dd570021.collapse_all(pt-br,VS.110).gifOperadores 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()

Dd570021.collapse_all(pt-br,VS.110).gifOperadores 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

Dd570021.collapse_all(pt-br,VS.110).gifOperadores 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()

Dd570021.collapse_all(pt-br,VS.110).gifOperadores 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)

Dd570021.collapse_all(pt-br,VS.110).gifOperadores 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çãoObservaçã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çãoObservaçã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çãoObservaçã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

Consulte também

Referência

Classe SafeIntException

Outros recursos

Diversas Classes de bibliotecas de suporte

Biblioteca SafeInt