《enum枚举用法攻略》一节已经介绍过枚举数据类型,还记得吗?它们是由程序员定义的数据类型,由一组称为枚举量的值组成,枚举量代表整数常量。本节将进一步介绍枚举数据类型的应用,以及使用它们能做和不能做的事情。
以下代码使用了两行来声明一个枚举数据类型,并定义了该类型的变量:
enum Car {PORSCHE, FERRARI, JAGUAR};
Car sportsCar;
但是,C++ 允许在同一个语句中声明一个枚举数据类型,并定义该类型的一个或多个变量。因此,上面的代码可以改写为如下形式:
enum Car {PORSCHE, FERRARI, JAGUAR} sportsCar;
以下语句不但声明了 Car 数据类型,而且定义了 2 个变量 myCar 和 yourCar:
enum Car {PORSCHE, FERRARI, JAGUAR} myCar, yourCar;
虽然枚举数据类型的枚举量在内存中是以整数形式存储的,但是,并不能直接将整数值赋给 enum 变量。例如,假设程序中包含以下声明:
enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY };
Day today;
现在可以编写以下赋值语句:
today = THURSDAY;
但是,正如前面已经介绍过的,以下语句是非法的。如果试图编译它,则会出现一个错误消息。
today = 3; //错误
在给 enum 变量赋值时,应该使用有效的枚举量。但是,如果某些情形要求必须将整数值存储在 enum 变量中,则可以通过强制转换的方式,将整数转换为 enum 数据类型,示例如下:
today = static_cast
该语句的作用与以下语句是一样的:
today = THURSDAY;
虽然不能直接将整数赋值给 enum 变量,但是,反过来却是可以的,即可以将枚举量赋值给整型变量。例如,以下代码将可以正常运行:
当该代码运行时,它将显示 3 4
。
虽然枚举量实际上就是整数,而且 enum 变量真正保存的也是整数值,但是,如果试图使用它们执行数学运算,那么还是会遇到问题。
例如,来看以下代码:
Day day1, day2; // 定义 2 个 Day 变量
day1 = TUESDAY; // 将 TUESDAY 赋值给 day1
day2 = day1 + 1; //错误!该语句不起作用
第 3 个语句之所以会出现问题,是因为表达式 day1+1 的结果为整数值 2,然后赋值运算符会试图将整数值 2 赋给 enum 变量 day2,但是前面已经介绍过,C++ 并不会隐式地将 int 转换为 Day 类型,所以出现了问题。
要解决该问题,可以如前文所述,通过强制转换的方式,将整数值结果转换为 Day 数据类型,示例如下:
day2 = static_cast
正如前文所述,将枚举量发送到 cout 将显示枚举量的整数值。例如,假设使用前面定义的 Day 类型,以下语句将显示 0:
cout << MONDAY << endl;
如果要让枚举量显示诸如“Monday”这样的字符串,则需要编写代码来产生所需的字 符串。例如,如果 workDay 是一个已经被初始化为某个值的 Day 变量,则以下switch语句将根据变量的值显示对应的日期名称:
因为枚举量是作为整数存储在内存中的,所以可以使用它们控制循环迭代的次数。但是,如前文所述,不能直接将数学运算的结果赋值给枚举量,而必须先将结果强制转换为 enum 数据类型。所以,不能直接对 enum 变量使用 ++ 或 -- 运算符。以下语句将无法运行。
要解决该问题,可以将以上语句修改为如下形式:
for ( Day workday = MONDAY; workday <= FRIDAY; workday = static_cast
但是,更简单的方法是将循环控制变量变成 int 类型。按照这个思路,可以将上面的语句修改如下:
C++ 不允许相同作用域内的多个枚举量具有相同的名称,也就是说,在同一作用域内,即使是两个不同的枚举数据类型,也不能定义或使用相同的枚举量名称作为自己的成员。但是,C++11 包含了一个新类型:enum,即所谓的强类型枚举,也称为 enum 类,可以摆脱这种限制。
以下是强类型 enum 声明的 2 个示例:
enum class Presidents { MCKINLEY, ROOSEVELT, TAFT };
enum class VicePresidents { ROOSEVELT, FAIRBANKS, SHERMAN };
以上语句定义了 2 个强类型 enum:Presidents 和 VicePresidents。注意,它们看起来和常规 enum 声明是一样的,区别在于,在 enum 后面多了一个单词 class。虽然这 2 个 enum 包含了相同的枚举量 ROOSEVELT,但是它们在编译时已经不会出错了。
但是,在使用强类型枚举数据类型时,必须给每个枚举量添加它所属 enum 名作为前缀,后接 ::
操作符。以下是 3 个示例:
Presidents prez = Presidents::ROOSEVELT; VicePresidents vp1 = VicePresidents::ROOSEVELT; VicePresidents vp2 = VicePresidents::SHERMAN;
第一个语句定义了名为 prez 的 Presidents 变量,并且使用了 Presidents::ROOSEVELT 枚举量作为它的初始化值;第二个语句定义了名为 vpl 的 VicePresidents 变量,并且使用了 VicePresidents::ROOSEVELT 枚举量作为它的初始化值;第三个语句定义了名为 vp2 的 VicePresidents 变量,并且使用了 VicePresidents::SHERMAN 枚举量作为它的初始化值。
请注意,即使枚举量 SHERMAN 是枚举数据类型中唯一的成员,也必须加上它所属的 enum 名称作为前缀。
以下是使用枚举量比较 prez 变量的if语句示例:
强类型枚举量和常规枚举量一样,也是作为整数存储的,但是,如果要检索一个强类型枚举量底层的整数值,则必须使用强制转换运算符。以下示例可以将 Presidents::ROOSEVELT 枚举量底层的整数值赋值给变量 x:
int x = static_cast
以下是另外一个示例,它显示了 Presidents::ROOSEVELT 和 Presidents::TAFT 枚举量的整数值:
cout<
在声明强类型 enum 时,可以选择性地指定任意整数数据类型作为底层类型。只要在 enum 名称后面加上一个冒号(:),然后跟上所需的数据类型即可。例如,以下语句声明了一个使用 char 数据类型作为其枚举量的 enum:
enum class Day : char { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY };
以下语句显示了另外一个示例。该语句声明了一个名为 Water 的 enum,使用了 unsigned 作为其枚举量的数据类型。此外,还给枚举量赋值了。
enum class Water : unsigned { FREEZING = 32, BOILING = 212 };
下面的程序演示了强类型枚举数据类型的用法:
纯文本复制
程序输出结果:
10 2