1. 聲明枚舉類型格式
enum Day{ Mon,Tue=5,Wed};//Mon=0;Tue=5;Wed=6
enumDay1{Mon1,Tue1,Wed1};//Mon1=0;Tue1=1;Wed1=2
enum {_Mon=2,_Tue,_Wed};//_Mon=2;_Tue=3;_Wed=4
enumDay2{Mo,Tu=3,We,Fr=4};//Mo=0,Tu=3,We=4,Fr=4
說說枚舉類型中的常量。
(1) 默認的枚舉中第一個爲0,此後每個加1。如果遇到給定值的,後面的都是給定值加1。
(2) 允許重複值的出現。
(3) 這些值都爲常量,不可修改。
(4) 可以通過“枚舉名::常量名”來訪問,也可以直接“常量名”來訪問(注意多個枚舉的重名問題)。
(5) 這些常量都會在編譯時,使用常數替換掉。
說說枚舉名。
(1) 和類名很像,屬於用戶自定義的數據類型。Enum就相當於class,枚舉名就相當於類名。
(2)sizeof(枚舉名),一般情況下等於int的size==4.
說說枚舉變量
(1) 可以通過枚舉名定義枚舉變量,注意枚舉變量只能使用兩種方式賦值:
enum Day{ Mon,Tue=5,Wed};//Mon=0;Tue=5;Wed=6
int _tmain(int argc, _TCHAR* argv[])
{
Dayd=Mon;//OK
d=Day(10);//OK
d=12;//ERROR
const int j=2;
d=j;//ERROR
return 0;
}
要麼是該枚舉常量中的值,要麼是通過該枚舉構造出來的值。
可以看出這些變量是可變的。
(2) 注意枚舉變量和類對象的不同。它們完全不同。
枚舉變量就相當於一個整型。它不擁有該枚舉定義好的常量,更不能“枚舉變量.枚舉常量”這麼使用。而類對象可以。
(3) 注意枚舉變量不可被賦值爲其他枚舉的常量
enum Day{ Mon,Tue=5,Wed};
enum D{a};
int _tmain(int argc, _TCHAR* argv[])
{
Daye=D::a;//ERROR
return 0;
}
2. 說說類中的枚舉
class A
{
public:enum as{a,b,c,d,e};
void foo(){int * a=newint[d];}//OK
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
A::asd=A::as::a;
cout<<sizeof(A)<<endl;//1
cout<<A::as::a<<endl;//0
return 0;
}
(1) 當枚舉在類中時,注意此時as只是一個數據類型,地位和A差不多,而a,b,c,d,e是枚舉常量。
(2) 該枚舉不佔內存,sizeof(A)=1.因爲此時還沒有定義枚舉變量。如果定義枚舉變量就相當定義int變量:
class A
{
public:enum as{a,b,c,d,e};
as s;
as s1;
};
int _tmain(int argc, _TCHAR* argv[])
{
cout<<sizeof(A)<<endl;//8
return 0;
}
(3) 可以通過“類名::枚舉名”來獲得這個枚舉類型。可以通過“類名::枚舉常量”來獲得該常量的值。
(4) 枚舉常量可以當作[]內的值,說明它的值在編譯期就被固定了。
總之:在類中的枚舉,有點像內部類的感覺,類中的枚舉常量,有點像類的conststatic常量。
枚舉有點像類,枚舉名有點像類名,而枚舉變量是整型變量,完全不同於類對象。枚舉常量就相當於const常量。
3. 枚舉常量和const、#define的不同之處
(1) 取一個const常量地址是合法的,而取一個枚舉常量的地址是不合法的。因爲編譯期會被替換爲常數。同理取一個#define地址也是不合法的。
(2) 雖然枚舉常量在編譯期會被替換,但是會將枚舉常量名保存在字符表中,如果後期有錯誤,編譯器知道這個常數是枚舉常量替換的。而#define也是在編譯期被替換爲常數,但是不保存宏名字,所以編譯器後期只能知道這個常數,不知道這個常數是被哪個宏名稱替換的。
4. 增加一些小知識
(1) 由於枚舉名是一個類型名,所以可作爲函數返回類型。
(2) 匿名定義一個枚舉變量:
enum {a,b,c,d,e} as;
int _tmain(int argc, _TCHAR* argv[])
{
as=b;
cout<<as<<endl;//1
return 0;
}
注意此時as是一個枚舉變量,不是枚舉名。
(3) 枚舉變量未初始化
如果該未初始化的枚舉變量定義在全局,則可以打印出其值爲0.
如果該未初始化的枚舉變量定義在主函數內部,則打印出錯。
(4) 枚舉變量不可以使用as++;這樣的東西。就像類對象一樣,是用戶自定義類型,不可以使用。
(5)有問題的代碼
enum as{a=1,b};
void foo(as l)
{
if(l==a){}do sth
else{}do sth because l must be b if l !=a.
}
這段代碼不能實習其本意。特別是這句話“lmust be b if l !=a.”因爲枚舉變量的值不一定必須是as枚舉常量,因爲還可以存在這樣的語句“l=as(10);”。
總結:枚舉變量不一定完全是枚舉常量的值。
(6) cin>>枚舉變量,是不合法的。cout<<枚舉變量,是合法的。
5. C++11加入的一些有關枚舉的東西
C++11中規定上面的以前的枚舉被成爲UnScoped枚舉。而現在我們又有了Scoped枚舉。
聲明:enumclass/struct e_Name {…};
定義枚舉變量沒啥區別。e_Namee1;不需加class/struct
和以往的區別:
(1) 使用的UnScoped枚舉常量時,前面必須加上枚舉名。“枚舉名::枚舉常量”。
(2) UnScoped枚舉常量不可以給int變量賦值。