1.enum
C++中enum提供了另一种创建符号常量的方法,这种方式可以替代const。enum也允许定义新类型,使用enum的语法与使用结构相似。如对下述示例:
enum color
{
red,
orange,
yellow,
black
};
有2个含义:
1)color称为新类型的名称,color被称为枚举,如同struct被称为结构体一个道理
2)red,orange,yellow,black等为符号常量,默认情况下对应数值0-3。这些常量叫枚举常量。枚举常量代表了该枚举类型color可能取得值。
3)red,orange,yellow,black的值0,1,2,3称为枚举值。
1)使用枚举名声明变量
color c;
c的取值只能是red,orange,yellow,black其中之一。
2)运算操作
枚举只定义了赋值运算符(=),没有算术运算(+-*/)
c=red;
c++;//错误
c=red+orange;//错误
3)枚举常量的取值
未设置时默认从0开始,依次递增。设置之后,按如下规则:
enum color{
one=1,
two=2,
three,
four,
five
};
///three,four,five的值依次为3,4,5
enum color{
one,
two,
three=10,
four,
five
};
one的值为0,two的值为1,four的值为101,five的值为102
enum color{
one,
two=0,
three,
four=1
five
};
///one的值为0,two的值为0,three的值为1,five的值为2
4)枚举的取值范围
对于下述示例
enum color{
one=1,
two=2,
three=4,
four=8
};
下述取值是合法的:
color c;
c=color(6);
c=6;错误,不能直接这样用
6不是枚举值,但在枚举定义的取值范围内。
上限计算:首先找到枚举量的最大值,然后找到大于这个值的最小的2的幂,将其减去1,得到取值范围的上限。如示例最大值为8,大于这个值得最小的2的幂是2^4=16,将16-1=15,故取值上限为15。
下限计算:首先确定枚举量的最小值,若最小值大于0,则取值范围的下限为0;若最小值小于0,先将最小值取反,然后找到大于取反后的最小值的最小的2的幂,将其减去1,将最终的结果前加负号,如最小值为-6,取反为6,最小的2的幂为8,8-1=7,取反得-7。
5)枚举的大小
枚举的大小默认为4字节,即一个int的大小,这也是上述1)-4)枚举值的取值为int的原因。
enum color{
one,
two,
three,
four,
five
};
cout<<sizeof(color)<<endl;
输出为4
在C++11中,允许在enum 类型名后接冒号加类型的方式来指定类型的发小。如以下几种方式:
enum color:char{
one,
two,
three,
four,
five
};
cout<<sizeof(color)<<endl;输出1
-----2
enum color:short{
one,
two,
three,
four,
five
};
cout<<sizeof(color)<<endl;///输出2
-----3
enum color:long{
one,
two,
three,
four,
five
};
cout<<sizeof(color)<<endl;输出8
-----4
enum color:long long{
one,
two,
three,
four,
five
};
cout<<sizeof(color)<<endl;///输出8
冒号后还可以使用uint8_t,uint16_t,uint32_t,uint64_t等多种类型。冒号后使用string ,float,double,会报错。
指定枚举类型的大小可以节省内存。
6)枚举的作用域
在枚举中定义的常量,属于定义枚举的作用域,不属于这个枚举类型。
enum color1{
red,
yellow
};
enum color2{
red,
yellow
};
上述示例会报错。提示red,yellow被重复定义。因为red,yellow并不属于color1,而是和color1同一个作用域。
在没有enum之前,C语言中enum的功能需要使用#define来完成,上述类似于
#define red 0
#define yellow 1
自然会提示重复定义。
解决方法1:修改枚举值的名称
enum color1{
red,
yellow
};
enum color2{
red1,
yellow1
};
解决方法2:使用命名空间
namespace name1{
enum color2{
red,
yellow
};
}
namespace name2{
enum color2{
red,
yellow
};
}
此时使用的话,比较繁琐,方式如下:
name2::color2 c=name2::red;
解决方法3:限定作用域 enum class
C++11引入了枚举限定作用域的概念,用法为:
enum class color1{
red,
yellow
};
enum class color2{
red,
yellow
};
此时可以通过如下方式直接使用
color1 c=color1:red;
2.enum class
enum class除了1.6提到的限定枚举的作用域,还有一个作用就是不能隐式转换为整数类型。
enum color{
red,
yellow
};
int r=red;///ok
cout<<r<<endl;///r=0
enum class color{
red,
yellow
};
int r=red;//error
int r=int(color1::red);///ok