C++11 推出的 强类型枚举(enum class)
的主要优势在于:
示例:
#include
enum class Color : int
{
Red,
Green,
Blue
};
enum class Car : int
{
Red,
Green,
Blue
};
int main() {
// 1、不会冲突,枚举值都有各自的作用域
Color color = Color::Red;
Color Car = Car::Red;
// 2、不能隐式转换成int
// int value = color;
if (color == Color::Red)
{
std::cout << "The color is red." << std::endl;
}
return 0;
}
缺乏类型安全性: 可以隐式转换为整数。不同枚举类型的值混淆。比如:
enum Color {red, green};
enum Car {BMW, Audi};
int main() {
Color color = red;
Car car = BMW;
if (color == car) // 这个if 是能通过编译的,很离谱
...
}
全局作用域: 传统的C风格枚举的成员在全局作用域中定义,这可能导致潜在的命名冲突。
enum Color {Red, Green, Blue};// 第一个文件
enum Color {Black, White};// 第二个文件
int main() {
enum Color color = Red; // 编译器不知道Red是哪个枚举的成员,因为有两个名为Color的枚举
printf("Color: %d\n", color); // 编译错误
...
}
给每个枚举添加命名空间可以解决,其实也不太麻烦。。
编译器可能会报警告 (但可以全局禁用它的警告)
没有底层类型: 传统的C风格枚举没有明确的底层类型,通常默认为int。这可能导致不同编译器和平台之间的兼容性问题,因为int的大小可能会有所不同
enum
还是enum class
?取决于具体需求!并不是 enum class
就一定好!
enum
的缺点恰恰就是它的优点
整型值: enum 可以完全等同于一个整型,因此可以像整数一样进行运算。这使得它非常适合需要进行位运算或其他整数运算的情况。
简洁: enum 的定义相对简单,不需要额外的运算符重载或其他复杂的结构。这使得代码编写和阅读都更为直观。
比如,你希望你的枚举值支持位运算,如果用enum class
,你需要重载你所需要的位运算操作符
#include
enum class FileAccess
{
READ = 1 << 0, // 1
WRITE = 1 << 1, // 2
EXECUTE = 1 << 2 // 4 为了方便做位运算,每个枚举值对应一个比特位为1
};
// 定义按位或运算符的重载
FileAccess operator|(FileAccess lhs, FileAccess rhs)
{
using T = std::underlying_type_t<FileAccess>;
return static_cast<FileAccess>(static_cast<T>(lhs) | static_cast<T>(rhs));
}
// ...其他运算符重载,如:& ^ ~ |= &= ^=
// 属实非常麻烦,如果还有其他类似的enum class 还要每个都写一遍,==噩梦
int main()
{
FileAccess myPermissions = FileAccess::READ | FileAccess::WRITE;
if (myPermissions & FileAccess::WRITE)
{
// 有写权限
}
return 0;
}
而使用enum,就非常简洁方便。
#include
enum FileAccess
{
READ = 1 << 0,
WRITE = 1 << 1,
EXECUTE = 1 << 2
};
int main()
{
FileAccess myPermissions = FileAccess::READ | FileAccess::WRITE;
if (myPermissions & FileAccess::WRITE) {
// ....
}
return 0;
}