在 C++ 中,枚举(或称为 enum
)是一种用户定义的数据类型,它由一组命名的整型常量组成。
创建(声明)枚举类型
要创建一个枚举(enum
),使用 enum
关键字后跟枚举名称和一对大括号内的命名值列表。
语法
创建枚举的语法如下:
enum enumName {
Enumerator_value1,
Enumerator_value2,
Enumerator_value3,
};
这里,
-
-
-
Enumerator_value1
, Enumerator_value2
, Enumerator_value3
等等是整型常量。
访问枚举
可以通过在 int main()
内部声明枚举与一个变量名并按需调用来访问枚举(enum
)。
语法
访问或调用枚举的语法如下:
enum enumName {
Enumerator_value1,
Enumerator_value2,
Enumerator_value3,
};
enumName enam_var = value;
这里,
-
-
variableName
是枚举符的名字(在枚举内定义的值)。
C++ 枚举示例
在下面的示例中,我们声明了一个枚举类型,声明了一个枚举的变量/对象,并访问了枚举常量。考虑以下示例:
#include <iostream>
using namespace std;
enum Day {
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday = 45,
Saturday
};
int main() {
Day get1 = Wednesday;
cout << get1 << endl;
cout << Saturday << endl;
return 0;
}
输出:
3
46
解释
在上面的代码中,默认情况下,每周的每一天都被分配了一个唯一的整数值,从0到6。然而,如果我们显式地给 Friday 分配值 45,枚举属性将导致序列从那个特定点继续,因此,Friday 和 Saturday 的值分别变为 45 和 46,从而完成进一步的序列。
C++ 枚举的类型
C++ 中通常有两种枚举:
-
非限定枚举(Unscoped Enums)
非限定枚举是 C++ 中传统的枚举形式。它们使用 enum
关键字定义,并且枚举符名称在包含范围内声明。由于枚举符名称被添加到了周围的范围内,这可能会导致名称冲突,除非仔细管理。它可以直接在代码中使用,就像一组代表特定数字的标签。
它自动分配从零开始的整数值,除非显式分配,并且可以隐式转换为整数。
示例:
#include <iostream>
using namespace std;
enum RGB {
Red,
Green,
Blue
};
void printColor(RGB color) {
switch (color) {
case Red: cout << "Color is Red"; break;
case Green: cout << "Color is Green"; break;
case Blue: cout << "Color is Blue"; break;
}
}
int main() {
RGB myColor = Red;
int value = myColor;
cout << "Integer value: " << value << endl;
printColor(myColor);
return 0;
}
输出:
Integer value: 0
Color is Red
-
限定枚举(Scoped Enums 或 enum class)
在 C++11 中引入的限定枚举使用 enum class
定义。它们提供更好的类型安全性和组织性,其中枚举符名称被限定在枚举内。这意味着保持它们的标签在一个特定组内,因此在使用它们时需要提及组名。这有助于避免在不同组中有相似标签的情况下的混淆。
枚举符名称限定在枚举类型内,这意味着必须使用枚举名称来访问它们。没有隐式转换为整数,这有助于增强类型安全性。
示例:
#include <iostream>
using namespace std;
enum class Color {
Red,
Green,
Blue
};
int main() {
Color myColor = Color::Red;
int value = static_cast<int>(myColor);
cout << "Integer value: " << value << endl;
return 0;
}
输出:
Integer value: 0
限定与非限定枚举对比
特性 |
非限定枚举 |
限定枚举(enum class) |
枚举符的作用域 |
全局作用域 |
限定在枚举类型内 |
名称冲突 |
可能 |
避免 |
隐式转换 |
是 |
否 |
类型安全性 |
较少 |
更多 |
基本类型 |
默认为 int |
可指定基本类型 |
比较枚举值
枚举值可以像整数比较一样进行比较。考虑以下示例:
#include <iostream>
using namespace std;
enum class Color {
Red,
Green,
Blue
};
int main() {
Color myColor = Color::Green;
if (myColor == Color::Green) {
cout << "The color is green!" << endl;
} else {
cout << "The color is not green." << endl;
}
return 0;
}
输出:
The color is green!
将枚举作为函数参数
你可以将枚举作为参数传递给函数。为了将枚举作为参数传递给函数,你需要指定枚举名称及其实例。
示例:
#include <iostream>
using namespace std;
enum class Color {
Red,
Green,
Blue
};
void printColor(Color color) {
switch (color) {
case Color::Red:
cout << "Red" << endl;
break;
case Color::Green:
cout << "Green" << endl;
break;
case Color::Blue:
cout << "Blue" << endl;
break;
}
}
int main() {
Color myColor = Color::Blue;
printColor(myColor);
return 0;
}
输出:
Blue
枚举的常见应用场景
以下是枚举的一些常见应用场景:
-
状态管理
enum class GameState {
MainMenu,
Playing,
Paused,
GameOver
};
-
配置选项
enum class LogLevel {
Info,
Warning,
Error,
Debug
};
-
命令类型
enum class Command {
Start,
Stop,
Pause,
Resume
};
-
方向和移动
enum class Direction {
Up,
Down,
Left,
Right
};
使用枚举的好处
-
提高可读性和维护性 — 枚举提供了有意义的值名称,使代码更清晰易懂,更容易维护。
-
类型安全和命名空间管理 — C++ 中的枚举限制了分配的值,特别是对于限定枚举,这减少了错误并避免了名称冲突。
-
有组织的代码结构 — 枚举通过将相关常量分组来帮助增强组织性,从而提高了代码可读性,强制类型安全,创建了更干净的函数接口,并促进了更容易的重构。
-
增强的功能性 — 枚举可以与
switch
语句顺利配合,并允许通过分配的值显式控制基础类型。
枚举的局限性
尽管有好处,但仍有一些局限性:
-
类型安全问题 — 非限定枚举可能导致名称冲突,并允许隐式转换为整数,这会增加错误风险。
-
有限的功能性 — 枚举具有一组固定的值,并且缺乏成员函数,这使其无法在运行时扩展。
-
调试困难 — 调试器可能会将枚举值显示为整数,这使得解释它们的意义更加困难。