枚举类型属于字面值常量类型,用于将一组整型常量组织在一起,每个枚举类型定义了一种新的类型。
C++包含两种枚举:限定作用域的和不限定作用域的。定义限定作用域的枚举类型的一般形式是:
enum calss(或 enum struct)枚举类型名 {..., ...};
定义不限定作用域的枚举类型时省略掉关键字class(或 struct)。如果enum是未命名的,则我们只能在定义该enum时定义它的对象。
在限定作用域的枚举类型中,枚举成员的名字遵循常规的作用域准则,而在不限定作用域的枚举类型中,枚举成员的作用域与枚举类型本身的作用域相同:
enum color { red, yellow, blue};
enum light { red, yellow, green}; //错误:重定义了枚举成员red, yellow
enum class peppers { red, yellow, pink}; //正确:枚举成员被隐藏了
color eyes = blue; //正确:不限定作用类的枚举类型的枚举成员位于有效作用域
peppers p = pink; //错误:peppers的枚举成员不在作用域中
color hair = color::red; //正确:允许显式地访问枚举成员
peppers p2 = peppers::red; //正确
只要enum有名字,我们就能定义并初始化该类型的成员。要想初始化enum对象或者为enum对象赋值,必须使用该类型的一个枚举成员或者该类型的另一个对象。
enum class open_modes { input, output, append };
open_modes om = 2; //错误:2不属于类型open_modes
open_modes om = open_modes::input; //正确
一个不限定作用域的枚举类型的对象或枚举成员能自动地转换成整型。而限定作用域的枚举类型则不会:
int i = color::red; //正确
int j = peppers::red; //错误
如果没有指定enum的潜在类型,则默认情况下限定作用域的enum成员类型是int。对于不限定作用域的枚举类型来说,其枚举成员不存在默认类型,我们只知道成员的潜在类型足够大,肯定能够容纳枚举值。如果我们指定了枚举成员的潜在类型(包括对限定作用的enum的隐式指定),则一旦某个枚举成员的值超出了该类型所能容纳的范围,将引发程序错误。
enum intValues : unsigned long long{
charTyp = 255, shortTyp = 65535, intTyp = 65535};
指定enum的潜在类型使得我们可以确保在一种实现环境中编译通过的程序所生成的代码与其他实现环境中生成的代码一致。
在C++11中,我们可以提前声明enum。enum的前置声明(无论隐式地还是显式地)必须指定其成员的大小。