C++中enum用法

枚舉類型,顧名思義,“枚”作爲量詞,作“個”講,那麼枚舉,就是一個一個的列舉,如果一件事情能夠被一個一個的列舉,那麼它的數量肯定就是有限的,否則是不能被一一列舉出來的。所以枚舉類型即爲能被列舉的常量的一個集合。

在生活中,枚舉的例子隨處可見,比如禮拜幾,那麼就可以作爲一個枚舉變量。這個變量所存儲的值,是有限的,且,能被我們所列舉。再比較說,性別。它也可以作爲一個枚舉類型,我們知道,性別也就只有“男”或者“女”,它是可以被我們所列舉的。它能很直觀的表達出我們所定義的事件。

如:定義一個枚舉類型的變量,雖然不知道變量具體是什麼值,但能知道它可能會有哪些值,這樣,這樣,就能對程序中所出現的變量的取值有一個很好的估量,從而使程序的編寫更加順利。

枚舉類型的定義寫結構體的定義相似,其形式爲:

enum 枚舉名{ 

標識符[=整型常數], 

標識符[=整型常數], 

... 

標識符[=整型常數], 

} 枚舉變量;

如果枚舉沒有初始化, 即省掉"=整型常數"時, 則從第一個標識符開始,

依次

次賦給標識符0, 1, 2, ...。但當枚舉中的某個成員賦值後, 其後的成員按依次 

加1的規則確定其值。

例如下列枚舉說明後, x1, x2, x3, x4的值分別爲0, 1, 2, 3。 

enum string{x1, x2, x3, x4}x; 

當定義改變成: 

enum string 

x1, 

x2=0, 

x3=50, 

x4, 

}x; 

則x1=0, x2=0, x3=50, x4=51 

注意: 

1. 枚舉中每個成員(標識符)結束符是",",

不是";", 最後一個成員可省略 

","。 

2. 初始化時可以賦負數, 以後的標識符仍依次加1。 

3. 枚舉變量只能取枚舉說明結構中的某個標識符常量。 

例如: 

enum string 

x1=5, 

x2, 

x3, 

x4, 

}; 

enum strig x=x3; 

此時, 枚舉變量x實際上是7。

4.在外部,我們可以對枚舉變量進行賦值,不過,得要進行類型轉換。

如果我們不進行類型輪換,即如下所示進行賦值:

x = 3;

是不允許是,如果對X進行賦值,只能對3進行類型轉換.即:

x = (string)3;

那麼這樣就對了.

如果給x賦的不是一個整形的數,而是一個字符型的,如:

x = (string)’a’;

那麼這時候x的值並不是字符’a’,而是’a’的ASCII碼,我們知道,在枚舉類型中,各常量的值只能是整形的,所以在對上例會自動的將’a’轉換成一個整數值.從內存的角度來看來話,其實C/C++中整形和字符型的變量是一樣的,它們之間可以互相轉換.

下面是一個使用枚舉類型的例子.(從網上收集得到)

#include <iostream>

#include <iostream>

using namespace std;

enum Day {Saturday, Sunday = 0, Monday, Tuesday, Wednesday,

Thursday, Friday}; //Saturday = 0 by default, Sunday = 0 as well

void Prnt (Day day)  // Print whether a day is a 'Weekend' or a "Weekday".

{

if (day ==0) cout << "Weekend" << endl;

else cout << "Weekday" << endl;

}

int main(){

enum Fruit {apple, pear, orange, banana} frt1; // 'frt1' can be declarated here.

// int apple; // error: redefinition of 'apple'

typedef enum Fruit ShuiGuo; // In c++, 'enum' can be omitted.

enum Fruit frt2 = apple; // In c++, 'enum' can be omitted.

ShuiGuo frt3 = pear; // After type-declaration synonym, 'enum' can not exist here!

frt1 = (Fruit) 0; // 'frt1' can be assigned with number by explicit cast.

for (int i = apple; i <= banana; i++)

switch (i)

{

case apple: cout << "apple" << endl; break;

case pear: cout << "pear" << endl; break;

case orange: cout << "orange" << endl; break;

case banana: cout << "banana" << endl; break;

default: break;

}

// Print whether a day is a 'Weekend' or a "Weekday".

Prnt (Saturday);

Prnt (Sunday);

Prnt (Monday);

Prnt (Tuesday);

Prnt (Wednesday);

Prnt (Thursday);

Prnt (Friday);

return 0;

}

C++ enum類型的一個更好的用法

enum 類型是c++的一個基本的類型,用於聲明可以枚舉的常量.相對於C#的enum, c++的enum有幾個缺陷:

1

不支持組合特性,也即FlagsAttribute屬性;

2

不支持toString方法,轉換爲字符串需要特別的函數實現;

3

不支持命名空間的特性.

前面的兩個比較明顯,我們只是討論第3個缺陷及其的一個彌補方法.

首先給出一段摘自MSDN的C#代碼:

public class EnumTest 

{

enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};

static void Main() 

{

int x = (int)Days.Sun;

int y = (int)Days.Fri;

Console.WriteLine("Sun = {0}", x);

Console.WriteLine("Fri = {0}", y);

}

}

代碼 1

C#使用枚舉

在上面的代碼中,枚舉類型Days不僅是一個類型,而且在使用當中還起到了命名空間的作用.

如果使用C++的代碼,應該是:

enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};

int main() 

{

int x = Sun;

//注意這裏!!

int y = Fri; 

//注意這裏!!

printf("Sun = {%d}", x);

printf ("Fri = {%d}", y);

return 0;

}

代碼 2

C++使用枚舉

在這裏,對enum類型,我們注意到C++和C#的兩個區別:

1

在C++中,enum向int的轉化是隱式進行的,不需要強制的類型轉換;

2

在C++中,使用枚舉類型不必帶有類型限定名,直接使用,類似於使用宏.

對於第一個區別,未必是一件壞事;但是對於第二個,則有明顯的問題.

我們列舉一個在c++中由於區別2而帶來問題的一個例子.假如我們聲明瞭另外的一個枚舉類型Planets: 

enum Planets {Moon, Earth, Sun }; 顯然,包含這個類型聲明的頭文件和代碼 2

是不能在一個編譯單元中使用的,因爲Sun意義有分歧.這顯然是C++枚舉類型缺乏命名空間所帶來的後果;對C#則沒有這樣的問題.

當然,c++這樣設計也有一些好處,我們也使用一個例子說明:

class File

{

public:

enum OpenMode{ READ, WRITE};

void open( OpenMode , const char* filename );

};

int main()

{

File file;

file.open(OpenMode::READ,"c:\\1.txt");

return 0;

}

代碼 3 C++枚舉不使用限定名適合的例子

我們注意到,這裏的代碼可讀性非常好.但是這段代碼的特點是:枚舉類型嵌套的定義在父類型裏面.但是在很多的情況下,枚舉類型具有獨立的意義,不必嵌套在任何的類型裏面,例如上面的代碼 1

.

要解決這個問題,傳統的做法有兩種:

1

仍然使用枚舉聲明,但是增加前綴,例如enum Days{Day_Sat=1, Day_Sun, Day_Mon, Day_Tue, Day_Wed, Day_Thu,Day_Fri}; enum Planets{ Planet_Moon, Planet_Earth, Planet_Sun };

2

不再使用枚舉聲明,使用int替代,並且嵌套在類型之中,例如 

struct Days

const static int Sat = 1;

const static int Sun = 2;

const static int Mon = 3;

const static int Tue = 4;

const static int Wed = 5;

const static int Thu = 6;

const static int Fri = 7;

};

struct Planets

{

const static int Moon = 0;

const static int Earth = 1;

const static int Sun = 1;

};

第一個方法顯得累贅,第二個方法則失去了枚舉類型的固有優點;我們希望提供一種把兩者結合起來的方法.

好了,囉嗦了這麼多,該拿出我們的乾貨了.下面是我們的方法:

namespace Days

{

enum Days_ {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};

};

typedef Days:ays_ Days;

int main()

{

Days d = Days::Sun;//1

int x = d;

printf("Sun = {%d}", x);

return 0;

}

代碼 4

C++ enum的用法

在代碼 4

的1中,Days出現在兩次,第一次是用作類型,實際上指向Days:ays_,第二次是用作命名空間,指向命名空間Days.那麼這個魔法是怎麼實現的呢?顯然,編譯器提供了智能化,爲我們完成了這個工作.

枚舉類型Days_爲什麼要有一個下劃線? 我們的目的是提醒用戶不要使用Days:ays_,而是使用我們定義的類型別名Days.

這個方法稍微繁瑣一點,但是滿足了我們的要求:使用枚舉類型(帶來枚舉類型固有的優點);使得枚舉類型具有命名空間的特點(雖然起這個作用的並不是枚舉類型本身).

原文地址:http://xiaocainiao.baijia.baidu.com/article/802200

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章