使用enum class代替enum

    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 };
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容