枚举

来源:互联网 发布:淘宝卖aj鞋子的好店 编辑:程序博客网 时间:2024/06/05 09:50

常规枚举

定义及特点

C++中的枚举是一个被命名的整型常数的集合。枚举在生活中很常见,例如表示星期的SundayMondayTuesdayWednesdayThursdayFridaySaturday,就是一个枚举。常规枚举常与switch语句配合使用以优化分支结构的表达。C++中这样定义:

enum Week {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};

枚举类型Week中,符号常量Sunday~Saturday分别对应整型0~6(在默认情况下),这些符号常量被称为枚举量,枚举量的实质是整型。

#include <string>#include <iostream>int main (void){    using std::cout;    using std::endl;    enum Week {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};    cout << Sunday << endl;    cout << Monday << endl;    cout << Tuesday << endl;    cout << Wednesday << endl;    cout << Thursday << endl;    cout << Friday << endl;    cout << Saturday << endl;    return 0;}



可以用枚举名来声明这种类型的变量并对其赋值,但在不进行强制类型转换的情况下只能将定义枚举时使用的枚举量赋给这种枚举变量:

Week week;//week为枚举变量week = Sunday;//合法赋值week = 0;//非法赋值

通过强制类型转换进行赋值:

week = Week(3);

week变量受到限制,只有7个可能的值,因此如果将一个不适当的值进行强制类型转换赋值给枚举类型,会得到不确定的结果。

虽然枚举量实质是整型,但C++只定义了枚举类型的赋值方法,没有定义算术运算,即诸如下列运算都是非法的:

week = Sunday+ Monday;非法语句week++;//非法语句

枚举量是整型,在需要类型转换的情况下C++允许其进行整型提升:

week = Sunday;int w = week;//枚举变量week将被提升为int型w = Sunday+3;//Sunday被提升为int型


可以使用赋值运算符来显式地设置一部分或全部枚举量的值,指定的值必须是整数:

#include <string>#include <iostream>#include <iomanip>int main (void){    using std::cout;    using std::endl;    using std::setw;    enum Week {Sunday, Monday = 3, Tuesday, Wednesday = 8, Thursday, Friday, Saturday};    cout << "   Sonday = " << setw(3) << Sunday << endl;    cout << "   Monday = " << setw(3) << Monday << endl;    cout << "  Tuesday = " << setw(3) << Tuesday << endl;    cout << "Wednesday = " << setw(3) << Wednesday << endl;    cout << " Thursday = " << setw(3) << Thursday << endl;    cout << "   Friday = " << setw(3) << Friday << endl;    cout << " Saturday = " << setw(3) << Saturday << endl;    return 0;}



除第一个枚举量外,未显式赋值的枚举量的值为相对于该枚举量的上一个显式赋值枚举量的位移,步长为1


Monday的赋值改为-1,可以看到,无论其余枚举量赋值如何,第一个枚举量若没有显式赋值,其值均为0

可以创建多个值相同的枚举量。


取值范围

每个枚举都有取值范围,通过强制类型转换,可以将取值范围中的任意整数值赋给枚举变量,即使这个值不是枚举值。例如下面一段代码中,我们定义一个枚举变量week,并这么赋值:

Week week;week = Week (5);//合法赋值

5不是枚举值,但它位于枚举定义的取值范围内。

在这段代码中甚至可以将13-7赋值给枚举变量week,因为13-7也在上述枚举的取值范围内。


#include <iostream>#include <iomanip>int main (void){    using std::cout;    using std::endl;    using std::setw;    enum Week {Sunday = -5, Monday = 3, Tuesday, Wednesday = 8, Thursday, Friday, Saturday};    cout << "   Sonday = " << setw(3) << Sunday << endl;    cout << "   Monday = " << setw(3) << Monday << endl;    cout << "  Tuesday = " << setw(3) << Tuesday << endl;    cout << "Wednesday = " << setw(3) << Wednesday << endl;    cout << " Thursday = " << setw(3) << Thursday << endl;    cout << "   Friday = " << setw(3) << Friday << endl;    cout << " Saturday = " << setw(3) << Saturday << endl;    Week week;    week = Week(13);    cout << "     week = " << setw(3) << week << endl;    week = Week(-7);    cout << "     week = " << setw(3) << week << endl;    return 0;}



枚举的取值范围定义:

首先要找出上限,需要知道枚举量的最大值,找到大于这个最大值的、最小的2的幂,将它减去1,得到的便是取值范围的上限。例如在Week枚举中,最大值为11,则大于11的最小的2的幂是24=16,因此其取值范围的上限就是15。要计算下限,需要知道枚举量的最小值。如果它不小于0,则取值范围的下限为0;否则,采用与上限方式相同的方式,但加上负号,并且加上1。例如在Week枚举中,最小值为-5,则小于-5的最大的2的幂是-23=-8,则其取值范围的下限就是-7

枚举的取值范围影响到枚举所占用的存储空间,因为选择用多少空间来存储枚举由编译器决定,对于取值范围较小的枚举,使用一个字节或更少的空间,而对于包括long类型值的枚举,则使用更大的空间。


作用域内枚举

作用域内枚举是C++11新增的一种枚举类型,旨在解决使用普通枚举定义作用域为类的常量时两个枚举定义中的枚举量发生冲突的问题。

例如在同一个类中作如下定义:

enum egg {Small, Medium, Large, Jumbo};enum T_shirt {Small, Medium, Large, XLarge};

上述两行代码编译时会出现问题,因为枚举eggT_shirt作用域相同,且枚举量重复。

使用作用域内枚举可以解决这个问题:

enum class egg {Small, Medium, Large, Jumbo};enum class T_shirt {Small, Medium, Large, XLarge};

也可用关键字struct代替class。无论使用哪种方式,都需要使用枚举名来限定枚举量:

egg choice = egg::Large;T_shirt Floyd = T_shirt::Large;

C++11还提高了作用域内枚举的类型安全。在有些情况下,常规枚举将自动转换为整型,但作用域内枚举不能隐式地转换为整型,但必要时可以显式类型转换。另外常规枚举用哪种整型类型表示取决于实现,因此包含枚举的结构的长度可能随系统而异。对于作用域内枚举,C++11取消了这种依赖性。默认情况下,C++11作用域内枚举的底层类型为int。但可以显式地改变底层类型:

enum class:short egg {Small, Medium, Large, Jumbo};//将枚举量的底层类型改为short



本文整理自《C++ Primer Plus(中文版)第6版》第章相关内容