
enum class),它是对传统 enum 的现代化改进,解决了传统枚举的多个问题,如命名冲突、隐式类型转换、作用域污染等。如:
enum Color {
RED,
GREEN,
BLUE
};
enum Light {
RED, // 编译错误!命名冲突
YELLOW
};
就是这个例子:

比如这里我们可以直接通过外接访问到这个成员:

int:
下面我们运行下:
root@hcss-ecs-7d13:/home/sw/linux_learn/extra_knowledge/enum_class# ./a.out
0发现结果就是0,明显自动隐式转换了。
这里就是我们上面暴露的问题的总结了,因此下面我们引入了C++的枚举类!
首先总结下它的特点,也就是对上面缺点的修正:
特性 | 说明 |
|---|---|
作用域隔离 | 枚举值只能通过 枚举类名::值 访问 |
类型安全 | 不允许隐式转换为 int |
可指定底层类型 | 可控制枚举值的存储大小 |
可读性高 | 代码结构清晰,易于维护 |
一般形式(当然我们一般默认成员都显转int,因此底层类型一般不写):
enum class 枚举类名 [: 底层类型] {
枚举值1,
枚举值2,
...
};简单使用比如还是那上面我们那个例子说明:
enum class Color {
Red,
Green,
Blue
};
enum class Light :uint32_t{
Red,
Yellow
};此时我们需要突破类域方式去访问了:

运行结果:
root@hcss-ecs-7d13:/home/sw/linux_learn/extra_knowledge/enum_class# ./a.out
Color is Red枚举类的底层类型(Underlying Type)enum class Color : uint8_t {
Red,
Green,
Blue
};sizeof(Color) 后结果:

常见底层类型:
int(默认)uint8_t / int8_tuint16_t / int16_tuint32_t / int32_tuint64_t / int64_t枚举类与整数的转换由于 enum class 不允许隐式转换,必须显式转换。
只能:
static_cast<int>(c);下面来验证下:
enum class Color : uint8_t {
Red,
Green,
Blue
};Color c = Color::Green;
int value = static_cast<int>(c);
std::cout << value << std::endl; 结果符合预期:

但是要是反过来呢?
Color c2 = static_cast<Color>(2);最后一个特点就明显不用说了吧!
作为函数参数void setColor(Color c) {
std::cout << "Setting color to: " << static_cast<int>(c) << std::endl;
} 输出:

作为函数返回值Color getFavoriteColor() {
return Color::Blue;
}这里如果我们强转成对应的类型uint8_t 此时就是这样:
std::cout<<static_cast< uint8_t>(favorite)<<std::endl;结果:

STX(Start of Text),它是不可见的,所以我们打印出来看不到!因此需要:
std::cout<<static_cast< int>(favorite)<<std::endl;就如下:

也就是我们通过对枚举成员进行switch操作,对指定枚举量安排指定操作(其他操作功能可自行拓展):
简单版如下:
enum class Color : uint8_t {
Red,
Green,
Blue
};
void printColor(Color c) {
switch (c) {
case Color::Red:
std::cout << "Color: Red\n";
break;
case Color::Green:
std::cout << "Color: Green\n";
break;
case Color::Blue:
std::cout << "Color: Blue\n";
break;
default:
std::cout << "Unknown color\n";
}
}下面我们测试一下:

<type_traits> 中的 std::underlying_type 可以获取枚举类的底层类型。下面我们测试下:
代码:
#include <iostream>
#include <type_traits>
enum class LevelType : uint16_t
{
UNKNOW = 0,
DEBUG,
INFO,
WARN,
ERROR
};
int main()
{
using underlying_type = std::underlying_type<LevelType>::type;
std::cout << "Underlying type size: " << sizeof(underlying_type) << " bytes\n";
return 0;
}结果如下:

符合预期!enum class 提供了类型安全和作用域隔离的优势,但它本身不支持直接附加描述信息或状态码。因此,我们常常需要通过类封装的方式,为枚举类添加描述、状态码、转换函数等功能。首先要知道和之前的普通枚举一样是可以类内自己给值的:
enum class Code {
OK=200,
NotFound=404,
InternalServerError=500
};但是下面我们通过封装类及提供接口方式来完成对应的设置获取等:
基于上述测试代码:
#include <iostream>
#include <string>
class HttpStatus {
public:
enum class Code {
OK,
NotFound,
InternalServerError
};
explicit HttpStatus(Code code) : code_(code) {}
// 获取状态码数值
int getStatusCode() const {
switch (code_) {
case Code::OK: return 200;
case Code::NotFound: return 404;
case Code::InternalServerError: return 500;
}
return -1; // 不应到达
}
// 获取状态描述
std::string getDescription() const {
switch (code_) {
case Code::OK: return "OK";
case Code::NotFound: return "Not Found";
case Code::InternalServerError: return "Internal Server Error";
}
return "Unknown Status";
}
// 打印状态信息
void print() const {
std::cout << getStatusCode() << " " << getDescription() << std::endl;
}
private:
Code code_;
};
int main(){
HttpStatus ok(HttpStatus::Code::OK);
HttpStatus notFound(HttpStatus::Code::NotFound);
HttpStatus serverError(HttpStatus::Code::InternalServerError);
ok.print();
notFound.print();
serverError.print();
return 0;
}
通过类封装,我们可以为枚举类添加描述、状态码、转换方法等高级功能,同时在 switch 中显式处理所有枚举值,确保逻辑完整性和代码健壮性。
一句话:
C++ 枚举类(enum class)是现代 C++ 编程中推荐使用的枚举形式,它解决了传统枚举的诸多问题,提高了代码的安全性、可读性和可维护性。
下面博主准备了关于它使用的顺口溜,帮助大家记忆:
枚举类,C++11,命名不冲突,作用域严。enum class 加限定,Red要加Color::才安全。隐式转换不允许,int转它要static_cast显。底层类型可指定,uint8_t省空间,嵌入式欢。switch要全覆盖,case别漏防出错,default保平安。封装功能更强大,加描述、状态码,类来管。类型安全最重要,enum class替旧版,代码稳!
传统枚举与枚举类对比:
特性 | 传统 enum | 枚举类 enum class |
|---|---|---|
命名冲突 | 容易发生 | 不会发生(作用域隔离) |
隐式转换 | 允许 | 不允许 |
作用域 | 枚举值暴露在外部 | 枚举值只在类内部可见 |
可读性 | 较差 | 更清晰、更安全 |
底层类型 | 不可指定 | 支持指定(如 int, char) |
可视化流程图:

本篇分享枚举类使用知识到这里,欢迎大家继续订阅本专栏学习更多知识来充实大脑。