- 无作用域枚举
enum Color {
Red, // Red的作用域不在Color内,而是整个文件,因此main函数中可以直接使用“Red”
Yellow
};
enum Color2 {
Red, // Red的作用域不在Color内,而是整个文件,因此main函数中可以直接使用“Red”
Yellow
};
namespace ABC {
enum Color {
Red, // Red的作用域不在Color内,而是ABC域内
Yellow
};
}
class DEF {
public:
enum Color {
Red, // Red的作用域不在Color内,而是DEF类内
Yellow
};
};
int main() {
Color x = Red;
Color2 x2 = Red; // 这里的Red和上面的Red产生冲突了,这就是无作用域的坏处
ABC::Color y = ABC::Red;
DEF::Color z = DEF::Red;
}
- 有作用域枚举(C++11起)
enum class Color {
Red, // Red的作用域在Color内
Yellow
};
enum class Color2 {
Red, // Red的作用域在Color2内
Yellow
};
int main() {
Color x = Color::Red;
Color x2 = Color2::Red; // 无冲突了
}
- 枚举项缺省使用0初始化,依次递增,可以使用常量表达式来修改缺省值
enum class Color {
Red,
Yellow = 100,
Green
};
class A {
public:
enum {x = 3}; // 早期的C++代码通过这种方式在类的内部定义一个编译期常量
// constexpr static int x = 3; // 这种方式更好,但早期C++不包含constexpr,所以用上面的方法代替
};
int main() {
std::cout << Color::Green << std::endl; // 101
}
- 可以为枚举指定底层类型,表明了枚举项的尺寸
enum Color {
Red,
Yellow = 100,
Green
};
enum Color2 : char {
Red,
Yellow = 100,
Green
};
int main() {
std::cout << sizeof(Color) << std::endl; // 4(int)
std::cout << sizeof(Color2) << std::endl; // 1
}
- 无作用域的枚举项可以隐式转换为整数,也可以用static_cast互相转换;有作用域的枚举项不可以
enum Color {
Red,
Yellow = 100,
Green
};
void fun(Color x) {
}
enum class Color2 {
Red,
Yellow = 100,
Green
};
int main() {
fun(100); // 编译失败
fun(static_cast<Color>(100)); // 编译成功
std::cout << Red << std::endl; // 0
std::cout << Color2::Red << std::endl; // 编译失败
std::cout << static_cast<int>(Color2::Red) << std::endl; // 编译成功
}
- 注意区分枚举的声明和定义
enum Color;
enum Color2 : int;
enum class Color3;
int main() {
Color x; // 即使在别的文件中有定义,还是失败;因为在这个翻译单元中,编译器不知道Color的具体大小是int还是char还是其他大小,无法分配内存
Color2 x; // 可以编译,Color2的大小确定
Color3 x; // 可以编译,有作用域的枚举类型默认是int型
}