Chapter 18: Enum Types¶
枚举在由命名常量的固定列表所组成的用户定义类型。在下面的示例中,枚举类型被称为Color,并且包含三个常量:red,green与blue。
enum class Color { red, green, blue };
Color类型可以用来创建存储这些常量值中的一个的变量。枚举类常量必须以枚举名为前缀,如下所示。
int main()
{
Color c = Color::red;
}
枚举示例¶
switch语句提供了枚举何时有用的良好示例。相比于使用普通常量,枚举具有允许程序员清晰表明变量应被允许包含什么值的优点。
switch(c)
{
case Color::red: break;
case Color::green: break;
case Color::blue: break;
}
枚举常量值¶
通常,无需了解常量表示的底层值,但有时,了解底层值会非常有用。默认情况下,枚举列表中的第一个常量值为零,而后续的每个常量值比前一个大1。
enum class Color
{
red, // 0
green, // 1
blue // 2
};
通过为常量赋值可以覆盖这些默认值。值可以被计算而无需唯一。未赋值的常量将会具有与前面已赋值的枚举值高的值。
enum class Color
{
red = 5, // 5
green = red, // 5
blue = green + 2, // 7
yellow // 8
};
枚举作用域¶
枚举并不一定要全局声明。它也可以被放置在类中作为类成员或是函数局部内。
class MyClass
{
enum class Color { red, green, blue };
};
void myFunction()
{
enum class Color { red, green, blue };
}
弱类型枚举¶
目前为止所描述的枚举类类型是由C++11引入为由C继承的弱类型枚举提供了一种安全的替换。旧的枚举类型定义与枚举类的定义方式相同,但无需class关键字。
// Weakly typed enum
enum Speed
{
fast,
normal,
slow
};
对于弱类型枚举,指定的常量并不属于枚举名字的作用域。因而这样的枚举常量可以无需枚举名进行引用。
Speed s1 = fast;
Speed s2 = Speed::normal;
由于枚举类的类型安全以及其常量限定于枚举名内,因而推荐使用枚举类而不是弱类型枚举。因为枚举类是强类型的,它们不会隐式转换为整数类型。
// Weakly typed enum
enum Speed { fast, normal, slow };
Speed s = fast;
if (s == fast) {} // ok
if (s == 0) {} // ok
// Strongly typed enum
enum class Color { red, green, blue };
Color c = Color::red;
if (c == Color::red) {} // ok
if (c == 0) {} // error
C++20添加了使用using语句将枚举类导入到局部作用域的能力。这可以例在特定的作用域内像普通枚举成员一样访问枚举类成员,从而避免枚举类名的重复。确否不要将枚举导入到一个过大的作用域内,否则会丢失使用强类型枚举的主要好处。
#include <iostream>
using namespace std;
enum class Color { red, green, blue };
void colorPrint(Color c)
{
// Import enum members to local scope
using enum Color;
switch (c)
{
case red: cout << "red";
case green: cout << "green";
case blue: cout << "blue";
}
}
枚举常量类型¶
标准并没有定义普通枚举底层的整数类型,并且会随着不同的实现而变化。相对应地,枚举类默认总是使用int类型。对于两种枚举类型,类型可以覆盖为另一种整数类型,如下面的示例所示。
// Enum with constant type set to unsigned short
enum class MyEnum : unsigned short {};