Declaración, definición y uso de enumeraciones

Como todos sabemos, el lenguaje C/C++ puede utilizar#defineyconstcrear constantes simbólicas, y usarenumLa herramienta no solo puede crear constantes simbólicas, sino también definir nuevos tipos de datos, pero debe realizarse siguiendo ciertas reglas. Veamos a continuaciónenumel método de uso.

Paso (1): Declaración y definición de enumeraciones

(1) Primero, observe la siguiente declaración:

enum enumType {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};

Esta declaración tiene dos funciones:

  • Primero: declara enumType como un nuevo tipo de dato, llamado enumeración (enumeration).
  • Segundo: declara Monday, Tuesday, etc. como constantes simbólicas, comúnmente llamadas enumeradores; sus valores por defecto son 0-6 respectivamente. (Más adelante se explicará cómo inicializar explícitamente los valores de los enumeradores).

(2)Luego, use el nuevo tipo de enumeración enumType para declarar una variable de este tipo: enumType Weekday, igual que se declara una variable con el tipo básico int, como int a; también se pueden definir variables de enumeración al definir el tipo de enumeración.

enum enumType {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday}Weekday;

Sin embargo, a diferencia de los tipos de variables básicos, sin una conversión forzada, solo se pueden asignar los enumeradores definidos a una variable de ese tipo de enumeración, por ejemplo: Weekday = Monday; o Weekday = Sunday; no se pueden asignar otros valores a una variable de enumeración, como Weekday = 10; esto no está permitido porque 10 no es un enumerador. Es decir, Weekday solo puede ser uno de los enumeradores definidos, Monday-Sunday. Sin embargo, esto no es absoluto; el sexto punto explicará cómo usar la conversión de tipo forzada para asignar valores de otros tipos a variables de enumeración.

(3)Arriba se dijo que no se puede asignar un no enumerador a una variable de enumeración, entonces, ¿se puede asignar un enumerador a una variable no enumerada? Por ejemplo:int a=Monday;Esto está permitido, porque el enumerador es una constante simbólica; en esta asignación el compilador convierte automáticamente el enumerador al tipo int.

(4)Antes se mencionó que se pueden realizar operaciones de asignación a la enumeración; ¿pueden las variables de enumeración realizar operaciones aritméticas?

Weekday++;Weekday = Monday + Tuesday;

Esto es ilegal, porque estas operaciones pueden violar las restricciones de tipo, por ejemplo:

Weekday = Sunday;
Weekday++;

Weekday primero se asigna al último valor del enumerador, Sunday (valor 6); si se incrementa, Weekday aumentaría a 7, pero para el tipo enumType, 7 no es válido.

Resumen:Para las enumeraciones, solo se define el operador de asignación; no se definen operaciones aritméticas para la enumeración.

(5)No se pueden realizar operaciones aritméticas con enumeradores; entonces, ¿pueden los enumeradores participar en operaciones con variables de otros tipos?

int a;
a = 1 + Monday;

Esto está permitido, porque el compilador convierte automáticamente el enumerador al tipo int.

(6)El segundo punto dice: sin conversión forzada, solo se pueden asignar los enumeradores definidos a variables de ese tipo de enumeración; en otras palabras, se pueden asignar valores de otros tipos a variables de enumeración mediante conversión forzada:

Weekday = enumType(2);

Equivale a:

Weekday = Wednesday;
Pero, ¿qué sucede si se intenta asignar a una variable de enumeración, mediante conversión forzada, un valor que está fuera del rango de valores de la enumeración?
Weekday = enumType(20);

El resultado será indefinido; hacerlo no causará un error, pero no se obtendrá el resultado deseado.

Paso (2): Personalizar los valores de las enumeraciones

(1)Antes se dijo que al definirenum enumType {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};Los valores de los enumeradores Monday, Tuesday, etc. son 0-6 por defecto; podemos establecer explícitamente los valores de los enumeradores:

enum enumType {Monday=1, Tuesday=2, Wednesday=3, Thursday=4, Friday=5, Saturday=6, Sunday=7};

¡Los valores especificados deben ser enteros!

(2)También se pueden definir explícitamente solo algunos valores de enumeradores:

enum enumType {Monday=1, Tuesday, Wednesday=1, Thursday, Friday, Saturday, Sunday};

Así, Monday y Wednesday se definen ambos como 1, entonces Tuesday=2, y los valores de Thursday, Friday, Saturday, Sunday son por defecto 2, 3, 4, 5 respectivamente.

Resumen:El valor de un enumerador no inicializado será, por defecto, 1 mayor que el valor del enumerador anterior.

(3)El segundo punto también muestra otro fenómeno: los valores de los enumeradores pueden ser iguales.

Paso (3): Rango de valores de la enumeración

Antes se mencionó que se pueden asignar valores de otros tipos a variables de enumeración mediante conversión forzada:

Weekday = enumType(2);

Esto es legal;

Pero

Weekday = enumType(20);

es ilegal. Aquí se involucra el concepto de rango de valores de la enumeración: el límite superior de la enumeración es la menor potencia de 2 mayor que el enumerador máximo, menos 1;

El límite inferior de la enumeración tiene dos casos: 1. Si el valor mínimo de los enumeradores no es menor que 0, entonces el límite inferior es 0; 2. Si el valor mínimo de los enumeradores es menor que 0, entonces el límite inferior es la mayor potencia de 2 menor que el enumerador mínimo, más 1.

Por ejemplo:

Si se defineenum enumType1 { First=-5,Second=14,Third=10 };Entonces el límite superior de la enumeración es 16-1=15 (16 es mayor que el enumerador máximo 14 y es una potencia de 2); el límite inferior de la enumeración es -8+1=-7 (-8 es menor que el enumerador mínimo -5 y es una potencia de 2).

Paso (4): Aplicaciones de la enumeración

Personalmente creo que las enumeraciones y switch son los mejores compañeros:

enum enumType{Step0, Step1, Step2}Step=Step0; // 注意这里在声明枚举的时候直接定义了枚举变量 Step,并初始化为 Step0

switch (Step)x
{
  case Step0:{...;break;}
  case Step1:{...;break;}
  case Step2:{...;break;}
  default:break;
}

Además, la enumeración tiene un uso poco común:enum { one ,two ,three};es no especificar un nombre; de este modo, naturalmente no podemos definir tipos de enumeración. En este caso equivale astatic const int one = 0;definir así tres constantes. Y su uso seríaint no = one。


Enumeraciones fuertemente tipadas

1. Breve introducción

Las enumeraciones fuertemente tipadas (Strongly-typed enums), denominadas tipos de enumeración, son una nueva sintaxis en C++11 para resolver los defectos de los tipos de enumeración tradicionales de C++. En C++ tradicional, las constantes de enumeración quedan expuestas en el ámbito externo; así, si en el mismo ámbito hay dos tipos de enumeración diferentes pero que contienen las mismas constantes de enumeración, esto no es posible, por ejemplo:

enum Side{Right,Left};
enum Thing{Wrong,Right};

Estos no se pueden usar juntos.

Otro defecto es que los valores de enumeración tradicionales siempre se convierten implícitamente a entero, y el usuario no puede personalizar el tipo. Las enumeraciones fuertemente tipadas en C++11 resuelven estos problemas.

2. Enumeraciones fuertemente tipadas

Las enumeraciones fuertemente tipadas se declaran con la sintaxis enum class, como sigue:

enum class Enumeration{
    VAL1,
    VAL2,
    VAL3=100,
    VAL4
};

De esta manera, el tipo de enumeración es seguro; los valores de enumeración tampoco se convierten implícitamente a enteros y no se pueden comparar con valores enteros, por ejemplo (Enumeration::VAL4==10 provocará un error de compilación).

Además, el tipo subyacente utilizado por el tipo de enumeración es int por defecto; también se puede especificar otro tipo, por ejemplo:

enum class Enum:unsigned int{VAL1,VAL2};

Como se dijo antes, las enumeraciones fuertemente tipadas resuelven el problema de los nombres de enumeradores iguales en diferentes clases de enumeración de las enumeraciones tradicionales. Al usar el nombre de un enumerador de un tipo de enumeración, se debe indicar el ámbito al que pertenece, por ejemplo: Enum::VAL1, mientras que VAL1 solo ya no tiene significado.

Otro punto que vale la pena mencionar es que la declaración anticipada de tipos de enumeración también es posible en C++11, por ejemplo:

enum class Enum;
enum class Enum1:unsigned int;

3. Fragmentos de código de enumeraciones fuertemente tipadas en proyectos

1. Procesamiento de imágenes

enum class Color{RED,BLUE,YELLOR,BLACK,WHITE};

2. Semáforo

enum class TrafficLight{RED,YELLOR,GREEN};

Los valores de enumeración fuertemente tipados tienen la funcionalidad de las enumeraciones tradicionales —nombrar valores de enumeración— y también tienen características de clase —miembros con ámbito de clase y sin conversión de tipo por defecto. Por eso también se les llama clases de enumeración —enmu class.

El tipo subyacente de la clase de enumeración debe ser un entero con o sin signo, como char, unsigned int, unsigned long; el valor predeterminado es int.

3. Aplicación de la declaración anticipada

enmu class Clolor:char;            //前置声明枚举类
void Foo(Color*p);                     //前置声明的使用
//....................
enum class Color:char{RED,GREEN,BLACK,WHITE};      //前置声明的定义

Referencia: http://blog.csdn.net/u012333003/article/details/20612267