C++11新特性之九:strongly-typed enums
一.傳統(tǒng)枚舉類型的缺點(diǎn)
1.作用域沖突
傳統(tǒng)C++中枚舉元素被暴漏在外層作用域中,這樣若是同一作用域下有兩個(gè)不同的枚舉類型,但含有相同的枚舉元素,就會(huì)產(chǎn)生沖突。
enum?EnumOne
{
????A?=?1,
????B?=?2
};
enum?EnumTwo
{
????A?=?1,
????C?=?2
};error C2365: “A”: 重定義;以前的定義是“枚舉數(shù)”
2.無(wú)關(guān)的枚舉元素可以比較
另外一個(gè)缺陷是傳統(tǒng)枚舉類型的枚舉元素總是被隱式轉(zhuǎn)換為整形,這就使得毫無(wú)關(guān)系的兩個(gè)枚舉類型的枚舉元素可以進(jìn)行比較。
enum?EnumOne
{
????A?=?1,
????B?=?2
};
enum?EnumTwo
{
????C?=?1,
????D?=?2
};
int?main()
{
????if?(EnumOne::A?==?EnumTwo::C)//?直接寫A==C也行
????{
??????????cout?<<?"equals"?<<?endl;//?輸出equals
????}
????if?(EnumOne::A?==?1)
????{
??????????cout?<<?"equals?too"?<<?endl;//?輸出equals?too
????}
????system("pause");
????return?0;
}二.強(qiáng)類型枚舉
強(qiáng)類型枚舉(Strongly-typed enums),號(hào)稱枚舉類型,是C++11中的新語(yǔ)法,用以解決傳統(tǒng)枚舉類型存在的缺點(diǎn)。
它不會(huì)將枚舉元素暴露到外層作用域中,也不會(huì)隱式轉(zhuǎn)換為整形,并且可以擁有用戶指定的元素類型(傳統(tǒng)枚舉也增加了這個(gè)性質(zhì))
強(qiáng)類型枚舉使用enum class語(yǔ)法來(lái)聲明,如下:
enum?class?EnumOne
{
????A?=?1,
????B?=?2
};
enum?class?EnumTwo
{
????A?=?1,
????C?=?2
};此時(shí)這兩個(gè)枚舉即使有同名元素A,編譯器不會(huì)報(bào)錯(cuò)了。
但是這兩個(gè)枚舉中枚舉元素的比較,或者枚舉元素與整數(shù)的比較都會(huì)報(bào)錯(cuò)。例如:
enum?class?EnumOne
{
????A?=?1,
????B?=?2
};
enum?class?EnumTwo
{
????A?=?1,
????D?=?2
};
int?main()
{
????if?(EnumOne::B?==?EnumTwo::D)//?A和B必須帶上作用域,不能直接寫成A==B,此時(shí)單獨(dú)的A或B不再有意義
????{
??????????cout?<<?"equals"?<<?endl;//?輸出equals
????}
????if?(EnumOne::B?==?2)
???{
??????????cout?<<?"equals?too"?<<?endl;//?輸出equals?too
???}
????system("pause");
????return?0;
}兩處相等判斷都在編譯時(shí)報(bào)錯(cuò):error C2678: 二進(jìn)制“==”: 沒(méi)有找到接受“EnumOne”類型的左操作數(shù)的運(yùn)算符(或沒(méi)有可接受的轉(zhuǎn)換)
三.比較
傳統(tǒng)枚舉類型和強(qiáng)枚舉類型都支持用戶指定元素類型(默認(rèn)為int類型)
enum?EnumA?:?int?{?A,B};
enum?class?EnumB?:?long?{C,D};還有一點(diǎn)值得說(shuō)明的是C++11中枚舉類型的前置聲明也是可行的,比如:
enum?Enum1;?????????????????????//?不合法 enum?Enum2?:?unsigned?int;??????//?合法的?C++11 enum?class?Enum3;???????????????//?合法的?C++11,默認(rèn)為int? enum?class?Enum4?:?unsigned?int;//?合法的?C++11 enum?Enum2?:?unsigned?short;????//?不合法的?C++11,Enum2已被聲明為unsigned?int
enmu?class?Clolor:char;???//前置聲明枚舉??
void?Foo(Color*p);????????//前置聲明的使用??
//....................??
enum?class?Color:char{RED,GREEN,BLACK,WHITE};?//前置聲明的定義四.一個(gè)例子
#includeusing?namespace?std;
int?main()
{
????enum?class?Status?{Ok,?Error};
????enum?struct?Status2{Ok,?Error};
????Status?flag?=?Status::Ok;
????if(flag?==?Status::Ok)
????{
?????????cout?<<?"equals"?<<endl;//equals
????}
????//int?n=flag;???????????????????//?錯(cuò)誤,不會(huì)隱式轉(zhuǎn)換為int
????int?n?=?static_cast(flag);?//?正確,?n?=?0,枚舉元素默認(rèn)從0開始
????enum?class?EnumOne?:?char?{?A?=?1,?B?=?2};???//指定枚舉的底層數(shù)據(jù)類型
????enum?class?EnumTwo?:?unsigned?int?{?C?=?1,?D?=?2,?Dbig?=?0xFFFFFFF0U?};
????cout?<<?sizeof(EnumOne::A)?<<?endl;??????????//?1
????cout?<<?(unsigned?int)EnumTwo::Dbig?<<?endl;?//?編譯器輸出一致,4294967280
????cout?<<?sizeof(EnumTwo::D)?<<?endl;??????????//?4
????cout?<<?sizeof(EnumTwo::Dbig)?<<?endl;???????//?4
????system("pause");
????return?0;
}




