Last updated:2026-10-12
C++ enum Enumerated Types¶
About the Author¶
WeChat official account:

Traditional Behavior¶
Enumerations have the following problems:
- Unrestricted scope, which easily leads to naming conflicts. For example, the following fails to compile:
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;
}
See the concrete implementation at: tradition_color.cpp
Classic Practice¶
A simple way to solve the naming conflicts caused by the unrestricted scope is to add a prefix when naming enumeration values, e.g. changing the example above to COLOR_BLUE and FEELING_BLUE.
Generally speaking, for the sake of consistency we prefix all the constants. But code that defines enumerations this way looks cumbersome. C programs may have to do it this way, though C++ programmers probably dislike this approach. The alternative is a namespace:
After that, you can define a new enumeration variable with Color::Type c = Color::RED;. After using namespace Color, the prefix can even be omitted, which simplifies the code. However, because a namespace can be extended with more content later on, the scope it provides is not very well sealed. In a large project, it is still possible for different people to give the same enumeration type name to different things.
A more "effective" approach is to use a class or a struct to restrict the scope, for example: defining new variables works the same way as with the namespace above, but now you need not worry about the class being modified elsewhere. A struct is used here rather than a class because we want these constants to be publicly accessible in the first place.
See the concrete implementation at: classic_practice.cpp
C++11 Enum Classes¶
The approach above solves the first problem but is powerless against the other two. Fortunately, the C++11 standard introduced "enum classes", which solve the problems above rather well.
- The scope of the new enum is no longer global
- No implicit conversion to other types
/**
* @brief C++11的枚举类
* 下面等价于enum class Color2:int
*/
enum class Color2
{
RED=2,
YELLOW,
BLUE
};
Color2 c2 = Color2::RED;
cout << static_cast<int>(c2) << endl; //必须转!
- A specific type can be specified to store the enum
enum class Color3:char; // 前向声明
// 定义
enum class Color3:char
{
RED='r',
BLUE
};
char c3 = static_cast<char>(Color3::RED);
See the concrete implementation at: classic_practice.cpp
Enumerated Types in Classes¶
Sometimes we want certain constants to be valid only inside a class. Since macros defined by #define are global, they cannot achieve this, so we think of using const-qualified data members instead. const data members do exist, but their meaning is not what we expect.
A const data member is constant only within the lifetime of a single object; for the class as a whole it is mutable, because the class can create multiple objects, and the const data members of different objects can have different values.
A const data member cannot be initialized in the class declaration. The following usage is wrong, because when no object of the class has been created, the compiler does not know what the value of SIZE is. (Before the C++11 standard)
The correct place is the initializer list of the class's constructor:
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
How can we establish a constant that holds throughout the whole class?
Do not count on const data members; use enumeration constants in the class instead. For example:
class Person{
public:
typedef enum {
BOY = 0,
GIRL
}SexType;
};
//访问的时候通过,Person::BOY或者Person::GIRL来进行访问。
Enumeration constants occupy no storage space in the object; they are all evaluated at compile time.
The drawback of enumeration constants is that their implicit data type is integer, their maximum value is limited, and they cannot represent floating point.
Related Topics¶
- C++ Pure Virtual Functions and Abstract Classes | C++那些事
- C++ assert | C++那些事
- C++ Bit Fields | C++那些事
- Implementing C++ Polymorphism in C | C++那些事
- C++ const Constants and Qualifiers | C++那些事
- The Complete C++ const Family | C++那些事
- C++ Dereference Operator * | C++那些事
- C++ Initialization and Assignment | C++那些事
- Ways to Return Multiple Values in C++ | C++那些事
- C++ mutable Keyword | C++那些事