C++之枚舉

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變量賦值。

 

發佈了45 篇原創文章 · 獲贊 32 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章