Inflexible enumeraciones en C ++

La programación es todo acerca de la legibilidad. Es difícil (en realidad es imposible) para escribir y mantener un programa que no se puede leer. Parte de la lectura de un listado de código fuente es la comprensión de lo que los números utilizados en el programa representan. La ayuda más básica que C ++ proporciona es el ubicuo #define, como en el siguiente ejemplo muy citado:

PI #define 3.141592653589793

Esta solución es aceptable para los valores individuales, aunque adolece del hecho de que la #define mecanismo no es (en sentido estricto) una parte de C / C ++ desde el preprocesador se ejecuta antes de que el compilador. En respuesta a eso, C ++ 2,011 introdujo una expresión constante construir:

constexpr long double PI = 3.141592653589793-

los contrastexpr palabra clave trae constantes en la tienda de la C ++. Esta PI tiene un tipo real, como variables de otra C ++. C ++ puede generar mensajes de error con PI que hacen mucho más sentido que los que implican 3,14159.

Las expresiones constantes están muy bien para valores constantes individuales, pero a menudo constantes representan conjuntos de cosas en lugar de constantes naturales, como en el siguiente ejemplo:

#define DC_OR_TERRITORY 0 # definen ALABAMA 1 # definen ALASKA 2 # define ARKANSAS 3 // ... y así sucesivamente ...

Es de suponer que estas constantes se utilizan para identificar los estados, tal vez se están utilizando como un índice en una matriz de objetos de estado o como un valor en una base de datos en alguna parte.

C ++ ha tenido durante mucho tiempo un mecanismo mejorado para la definición de estos tipos de constantes - la enumeración:

enum ESTADO {// DC_OR_TERRITORY, consigue 0ALABAMA, // obtiene 1ALASKA, // obtiene 2ARKANSAS, // ... y así sucesivamente ...} -

los enum palabra clave introduce una secuencia de constantes llamado "empadronamiento". En este caso, la enumeración lleva el nombre ESTADO. Cada elemento de esta enumeración se le asigna un valor a partir de las 0 y aumentando secuencialmente por 1, por lo que DC_OR_TERRITORY se define como 0, ALABAMA se define como 1, y así sucesivamente. Puede anular esta secuencia gradual mediante el uso de una declaración de asignación de la siguiente manera:

enum ESTADO {DC, TERRITORIO = 0, Alabama, Alaska, // ... y así sucesivamente ...} -

Esta versión de ESTADO define un elemento Corriente continua, que se le da el valor 0. A continuación, define un nuevo elemento TERRITORIO, que también se le asigna el valor 0. ALABAMA recoge con 1, igual que antes.

En la práctica, el programador puede utilizar enumeraciones escribir código muy legible como el siguiente:

doble TaxRate (s ESTADO) {return taxRatesByState [s] -}

El único problema con este enfoque es que esta enumeración no crea un nuevo tipo (como se podría pensar). De hecho, de acuerdo con la norma, ESTADO es sólo otro nombre para int - y las constantes ALABAMA, ALASKA, y así sucesivamente son todos de tipo const int.

El compilador gcc realidad proporciona una enum declarado de esta manera un poco más autoridad que simplemente llamando a otra forma de int. En realidad se puede sobrecargar funciones sobre la base de una enum escribe:

void fn (s ESTADO) fn -void (int n) -fn (ALASKA) - // invoca fn (ESTADO)

La norma de 2011 permite al programador crear un tipo completamente nuevo mediante el enum palabra clave. Dado que los creadores de la nueva norma no querían romper el código existente, la norma requiere la adición de una palabra clave adicional para definir un tipo de enumeración, como en el siguiente ejemplo:

clase enum ESTADO {DC, TERRITORIO = 0, Alabama, Alaska, // ... y así sucesivamente ...} -

Una clase de enumeración es ahora un tipo a gran escala como cualquier otra clase definida por el usuario. Lo siguiente no es aún legal más por dos razones:

int s = Alaska-

En primer lugar, la constante ALASKA solamente se define dentro de la ESTADO espacio de nombres. Así, el nombre de la constante es ESTADO :: ALASKA. En segundo lugar, el tipo no es int pero ESTADO. No se puede asignar un valor de tipo ESTADO a un int.

ESTADO s = ESTADO :: Alaska-

El programador puede refundir un ESTADO en una int pero debe hacerlo de forma explícita conversiones -implicit no lo cortan con las clases de enumeración:

int n = (int) ESTADO :: Alaska-

Este nuevo tipo de enumeración también se puede basar en uno de los otros tipos de número de recuento, además de sólo int:

clase enum ESTADO: char {DC, // ... el resto de la declaración es el mismo



» » » » Inflexible enumeraciones en C ++