enum Alert { green, yellow, orange, red }; // traditional enum
enum class Color { red, blue }; // new enum
C++11里面提出了一個(gè)新的概念enum class
。它的特點(diǎn)是。
新的enum的作用域不在是全局的了。
原來enum名字的作用域是全局的。
Alert a1 = red; //ok
Alert a2 = Alert::red; //error in C++98; ok in C++11
int red = 0; // error, red is redefined
而新的enum class
的名字是處于類的作用域里面的。
Color c1 = Color::blue; //ok
Color c2 = blue; // error
int blue = 0; //ok, blue is in class scope
不能隱式轉(zhuǎn)換成其他類型
int i = Alert::red; //ok for old enum
int k = Color::blue; // error for new enum
這個(gè)特性我特別喜歡,可以有更嚴(yán)格類型系統(tǒng),本來red和blue和數(shù)字就是兩個(gè)系統(tǒng)的東西,沒理由互相轉(zhuǎn)換。
C++11里面可以指定用特定的類型來存儲(chǔ)enum值了。
看下面這個(gè)問題,struct Data
是對(duì)應(yīng)著某個(gè)硬件的寄存器,所以這里我們使用了固定精度的整形uint8_t
,然后使用了#pragma pack(push, 1)
來禁止了結(jié)構(gòu)體內(nèi)部的padding。對(duì)于flag,我一項(xiàng)喜歡使用enum,而不是宏來定義。但是在C++11以前,enum值的大小是一個(gè)編譯器相關(guān)的事情,所以在這個(gè)場景下,struct Data
大小必須和硬件寄存器一樣,所以就不能用enum來作為flag的類型。
#define FLAG_1 (0x1)
#define FLAG_2 (0x2)
#define FLAG_3 (0x4)
#pragma pack(push, 1)
struct Data{
uint8_t data1;
uint16_t flag;
uint8_t data2;
};
#pragma pack(pop)
在C++11里面,enum的大小是可以指定的了,像下面這樣。
enum Alert : int { green, yellow, orange, red };
enum class Color : unsigned char { red, blue };
所以前面的那段代碼,我基本上會(huì)寫成下面這樣,使用enum FLAG
代替uint16_t
來聲明flag了。
#pragma pack(push, 1)
struct Data{
enum FLAG : uint16_t {
FLAG_1 = 0x1,
FLAG_2 = 0x2,
FLAG_3 = 0x4
};
uint8_t data1;
FLAG flag;
uint8_t data2;
};
#pragma pack(pop)
Data d = { 1, Data::FLAG_1, 2 };