一.傳統枚舉類型的缺點
1.作用域沖突
傳統C++中枚舉元素被暴漏在外層作用域中,這樣若是同一作用域下有兩個不同的枚舉類型,但含有相同的枚舉元素,就會産生沖突。
enum EnumOne
{
A = 1,
B = 2
};
enum EnumTwo
{
A = 1,
C = 2
};
error C2365: “A”: 重定義;以前的定義是“枚舉數”
2.無關的枚舉元素可以比較
另外一個缺陷是傳統枚舉類型的枚舉元素總是被隐式轉換為整形,這就使得毫無關系的兩個枚舉類型的枚舉元素可以進行比較。
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;
}
二.強類型枚舉
強類型枚舉(Strongly-typed enums),号稱枚舉類型,是C++11中的新文法,用以解決傳統枚舉類型存在的缺點。
它不會将枚舉元素暴露到外層作用域中,也不會隐式轉換為整形,并且可以擁有使用者指定的元素類型(傳統枚舉也增加了這個性質)
強類型枚舉使用enum class文法來聲明,如下:
enum class EnumOne
{
A = 1,
B = 2
};
enum class EnumTwo
{
A = 1,
C = 2
};
此時這兩個枚舉即使有同名元素A,編譯器不會報錯了。
但是這兩個枚舉中枚舉元素的比較,或者枚舉元素與整數的比較都會報錯。例如:
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,此時單獨的A或B不再有意義
{
cout << "equals" << endl;// 輸出equals
}
if (EnumOne::B == 2)
{
cout << "equals too" << endl;// 輸出equals too
}
system("pause");
return 0;
}
兩處相等判斷都在編譯時報錯:error C2678: 二進制“==”: 沒有找到接受“EnumOne”類型的左操作數的運算符(或沒有可接受的轉換)
三.比較
傳統枚舉類型和強枚舉類型都支援使用者指定元素類型(預設為int類型)
enum EnumA : int { A,B};
enum class EnumB : long {C,D};
還有一點值得說明的是C++11中枚舉類型的前置聲明也是可行的,比如:
enum Enum1; // 不合法
enum Enum2 : unsigned int; // 合法的 C++11
enum class Enum3; // 合法的 C++11,預設為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}; //前置聲明的定義
四.一個例子
#include <iostream>
using 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; // 錯誤,不會隐式轉換為int
int n = static_cast<int>(flag); // 正确, n = 0,枚舉元素預設從0開始
enum class EnumOne : char { A = 1, B = 2}; //指定枚舉的底層資料類型
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;
}