SafeInt (Clase)

 

Para obtener la documentación más reciente de Visual Studio 2017 RC, consulte documentación de Visual Studio 2017 RC.

Extender los primitivos fundamentales para ayudar a evitar el desbordamiento de enteros y permiten comparar diferentes tipos de enteros.

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

Parámetros

PlantillaDescripción
TEl tipo de parámetro entero o boolean que SafeInt reemplaza.
EUn tipo de datos enumerado que define la directiva de control de errores.
UEl tipo de parámetro entero o boolean para el operando secundario.
ParámetroDescripción
[in] lado derechoUn parámetro de entrada que representa el valor de la derecha del operador en varias funciones independientes.
[in] iUn parámetro de entrada que representa el valor de la derecha del operador en varias funciones independientes.
[in] bitsUn parámetro de entrada que representa el valor de la derecha del operador en varias funciones independientes.

Constructores públicos

NameDescripción
SafeInt::SafeIntConstructor predeterminado.

Operadores de asignación

NameSintaxis
=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 conversión

NameSintaxis
booloperator bool() throw()
charoperator char() const
signed charoperator signed char() const
unsigned charoperator unsigned char() const
__int16operator __int16() const
unsigned __int16operator unsigned __int16() const
__int32operator __int32() const
unsigned __int32operator unsigned __int32() const
longoperator long() const
unsigned longoperator unsigned long() const
__int64operator __int64() const
unsigned __int64operator unsigned __int64() const
wchar_toperator wchar_t() const

Operadores de comparación

NameSintaxis
<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

NameSintaxis
+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

NameSintaxis
!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&#124; (SafeInt<T,E> rhs) const throw()
|template<typename U>

 SafeInt<T,E> operator&#124; (U rhs) const throw()
|=SafeInt<T,E>& operator&#124;= (SafeInt<T,E> rhs) throw()
|=template<typename U>

 SafeInt<T,E>& operator&#124;= (U rhs) throw()
|=template<typename U>

 SafeInt<T,E>& operator&#124;= (SafeInt<U, E> rhs) throw()

La clase de SafeInt protege contra el desbordamiento de enteros en operaciones matemáticas. Por ejemplo, considere agregar dos enteros de 8 bits: uno tiene un valor de 200 y el segundo tiene un valor de 100. La operación matemática correcta se 200 + 100 = 300. Sin embargo, debido al límite entero de 8 bits, el bit superior se perderán y el compilador devolverá 44 (300 - 28) como resultado. Cualquier operación que depende de esta ecuación matemática generará un comportamiento inesperado.

La clase de SafeInt comprueba si un desbordamiento aritmético aparece o si el código intenta dividir por cero. En ambos casos, la clase llama al controlador de errores para advertir el programa del problema.

Esta clase también permite comparar dos tipos de enteros mientras son objetos de SafeInt . Normalmente, cuando se realiza una comparación, primero debe convertir números con el mismo tipo. El inicio de un número a otro tipo requiere a menudo comprobaciones asegurarse de que no haya pérdida de datos.

La tabla de los operadores de este tema muestra el matemático y operadores de comparación admitidos por el tipo de SafeInt . La mayoría de los operadores matemáticos devuelven un objeto de SafeInt de Tescrito.

Las operaciones de comparación entre SafeInt y un tipo entero se pueden realizar en cualquier dirección. Por ejemplo, SafeInt<int>(x) < y y y > SafeInt<int>(x) son válidos y devolverán el mismo resultado.

Muchos operadores binarios no admiten mediante dos tipos diferentes de SafeInt . Un ejemplo de esto es el operador de & . se admiteSafeInt<T, E> & int , pero SafeInt<T, E> & SafeInt<U, E> no. En el último ejemplo, el compilador no conoce el tipo de parámetro a devolver. Una solución a este problema es convertir el segundo parámetro al tipo base. Utilizando los mismos parámetros, esto se puede hacer con SafeInt<T, E> & (U)SafeInt<U, E>.

System_CAPS_ICON_note.jpg Nota

Para cualquier operación bit a bit, los dos diferentes parámetros deben tener el mismo tamaño. Si difieren tamaños, el compilador produce una excepción de ASSERT . Los resultados de esta operación no pueden garantizar para ser precisos. Para resolver este problema, convierta el parámetro menor hasta que el mismo tamaño que el parámetro mayor.

Para los operadores de cambio, al desplazarse más bits que existe para el tipo de plantilla producirá una excepción ASSERT. Esto no tendrá ningún efecto en modo de lanzamiento. Mezclar dos tipos de parámetros SafeInt es posible que los operadores de cambio porque el tipo de valor devuelto es el mismo que el tipo original. El número a la derecha del operador sólo indica el número de bits al cambio.

Cuando se realiza una comparación lógica con un objeto SafeInt, la comparación es estrictamente aritmética. Por ejemplo, considere estas expresiones:

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

  • ((uint)~0) > -1

La primera instrucción cumple a true, pero la segunda instrucción se resuelve como false. La negación bit a bit de 0 es 0xFFFFFFFF. En la segunda instrucción, el operador de comparación predeterminado compara 0xFFFFFFFF a 0xFFFFFFFF y se considera igual. El operador de comparación de la clase de SafeInt detecta que el segundo parámetro es negativo como primer parámetro es sin signo. Por consiguiente, aunque la representación de bits es idéntica, el operador lógico de SafeInt detecta que el entero sin signo es mayor de -1.

Tenga cuidado al utilizar la clase de SafeInt junto con el operador ternario de ?: . Considere la siguiente línea de código.

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

El compilador lo convierte a:

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

Si flag es false, el compilador produce una excepción en lugar de asignar el valor de -1 a x. Por consiguiente, para evitar este comportamiento, código correcto para utilizar es la línea siguiente.

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

T y U se pueden asignar un tipo booleano, el tipo de caracteres, o el tipo integer. Los tipos enteros pueden ser firmados o sin signo y cualquier tamaño a partir de 8 bits a 64 bits.

System_CAPS_ICON_note.jpg Nota

Aunque la clase de SafeInt acepta cualquier tipo de entero, realiza más eficazmente con tipos sin signo.

E es el mecanismo de control de errores que SafeInt utiliza. Dos mecanismos de control de errores se proporcionan la biblioteca SafeInt. La directiva predeterminada es SafeIntErrorPolicy_SafeIntException, que produce una excepción de SafeIntException (Clase) cuando se produce un error. Otra directiva es SafeIntErrorPolicy_InvalidParameter, que detiene el programa si se produce un error.

Hay dos opciones para personalizar la directiva del error. La primera opción es establecer el parámetro E cuando se crea SafeInt. Use esta opción si desea cambiar la directiva de control de errores para un solo SafeInt. Otra opción es definir _SAFEINT_DEFAULT_ERROR_POLICY para ser la clase de control de errores antes de que incluye la biblioteca de SafeInt . Use esta opción si desea cambiar la directiva predeterminada de control de errores para todas las instancias de la clase de SafeInt en el código.

System_CAPS_ICON_note.jpg Nota

Una clase personalizada que controla los errores de la biblioteca SafeInt no debe devolver el control al código que llamó al controlador de errores. Después de llamar al controlador de errores, el resultado de la operación de SafeInt no se puede confirmar.

Encabezado: safeint.h

msl::utilities deEspacio de nombres:

Clases admiten distintas de las bibliotecas
SafeInt (Biblioteca)
SafeIntException (Clase)

Mostrar: