Última actualización:2026-10-12
Tipos de enumeración enum en C++¶
Sobre el autor:¶
Cuenta pública personal de WeChat:

Comportamiento tradicional¶
Las enumeraciones tienen los problemas siguientes:
- El ámbito no está restringido, lo que provoca fácilmente conflictos de nombres. Por ejemplo, lo siguiente no llega a compilar:
enum Color
{
RED,
BLUE
};
enum Feeling
{
EXCITED,
BLUE
};
int main()
{
Color a = BLUE; // error
Feeling b = EXCITED;
std::cout << a << ":" << b << std::endl;
return 0;
}
```- Se convierten implícitamente a int
- El tipo real que representa a la variable de enumeración no puede especificarse explícitamente, por lo que no se admite la declaración previa de tipos de enumeración.
Para la implementación concreta, consulta: [tradition_color.cpp](https://github.com/Light-City/CPlusPlusThings/tree/master/basic_content/enum/tradition_color.cpp)
## Enfoque clásico
Una forma simple de resolver los conflictos de nombres causados por el ámbito no restringido es añadir un prefijo al nombrar las variables de enumeración, cambiando por ejemplo el caso anterior a COLOR_BLUE y FEELING_BLUE.
En general, por coherencia, añadiríamos el mismo prefijo a todas las constantes. Pero definir así las variables de enumeración resulta pesado. En programas C quizá no quede más remedio. Sin embargo, a quien programa en C++ este método no le gusta nada. La alternativa son los espacios de nombres:
```c++
namespace Color
{
enum Type
{
RED=15,
YELLOW,
BLUE
};
};
Color::Type c = Color::RED; para definir nuevas variables de enumeración. Si se escribe using namespace Color, el prefijo puede omitirse y el código se simplifica. Sin embargo, como un espacio de nombres puede ampliarse después, el cierre de ámbito que ofrece no es muy fuerte. En proyectos grandes sigue siendo posible que distintas personas den el mismo nombre de tipo de enumeración a cosas distintas.
El método más “eficaz” es usar una clase o una estructura para restringir su ámbito; por ejemplo: la forma de definir nuevas variables es la misma que con el espacio de nombres anterior. Eso sí, así no hay que preocuparse de que la clase se modifique en otro lugar. Aquí se usa una estructura en lugar de una clase porque, de entrada, se quiere que estas constantes sean accesibles públicamente.
Para la implementación concreta, consulta: classic_practice.cppLas clases de enumeración de C++11¶
El enfoque anterior resuelve el primer problema, pero nada puede hacer con los otros dos. Afortunadamente, el estándar C++11 introdujo las “clases de enumeración” (enum class), que resuelven bastante bien los problemas anteriores.
- El ámbito del nuevo enum ya no es global
- No puede convertirse implícitamente a otros tipos
/**
* @brief C++11的枚举类
* 下面等价于enum class Color2:int
*/
enum class Color2
{
RED=2,
YELLOW,
BLUE
};
Color2 c2 = Color2::RED;
cout << static_cast<int>(c2) << endl; //必须转!
enum class Color3:char; // 前向声明
// 定义
enum class Color3:char
{
RED='r',
BLUE
};
char c3 = static_cast<char>(Color3::RED);
Tipos de enumeración dentro de una clase¶
A veces queremos que ciertas constantes solo sean válidas dentro de una clase. Como las constantes de macro definidas con #define son globales y no sirven para ello, se piensa en usar miembros de datos calificados con const. Y ciertamente los miembros de datos const existen, pero su significado no es el que esperamos.
Un miembro de datos const solo es constante durante la vida de un objeto concreto, pero para la clase entera es variable, porque la clase puede crear varios objetos y el valor del miembro de datos const puede ser distinto en cada uno.
No se puede inicializar un miembro de datos const en la declaración de la clase. El uso siguiente es erróneo, porque mientras no se cree el objeto de la clase el compilador no sabe cuánto vale SIZE. (antes del estándar C++11)
Lo correcto es hacerlo en la lista de inicialización del constructor de la clase:class A
{
A(int size); // 构造函数
const int SIZE ;
};
A::A(int size) : SIZE(size) // 构造函数的定义
{
}
A a(100); // 对象 a 的 SIZE 值为 100
A b(200); // 对象 b 的 SIZE 值为 200
No cuentes con los miembros de datos const; debe hacerse con constantes de enumeración dentro de la clase. Por ejemplo:
class Person{
public:
typedef enum {
BOY = 0,
GIRL
}SexType;
};
//访问的时候通过,Person::BOY或者Person::GIRL来进行访问。
El inconveniente de las constantes de enumeración es que su tipo de datos implícito es entero, su valor máximo es limitado y no puede representar números en coma flotante.
Temas relacionados¶
- Funciones virtuales puras y clases abstractas en C++ | C++那些事
- Aserciones assert en C++ | C++那些事
- Campos de bits en C++ | C++那些事
- Implementar el polimorfismo de C++ en lenguaje C | C++那些事
- const en C++: constantes y modificación | C++那些事
- La familia completa de const en C++ | C++那些事
- El operador de desreferencia * en C++ | C++那些事
- Inicialización y asignación en C++ | C++那些事
- Formas de devolver varios valores en C++ | C++那些事
- La palabra clave mutable en C++ | C++那些事