解讀C++中枚舉(enum)的使用
前言
對于開發(fā)C++來說,枚舉是一個幾乎必然用到的功能。當(dāng)然今天要講的枚舉肯定不是平常漫不經(jīng)心的使用,而是從里到外地深扒它,逐漸揭開它神秘地面紗,發(fā)現(xiàn)一些未曾注意到地東西。
一、枚舉是什么
枚舉(enumeration)類型用于存放用戶指定的一組整數(shù)值(§iso.7.2)。枚舉類型的每種取值各自對應(yīng)一個名字,我們把這些值叫做枚舉值(enumerator)。
二、使用步驟
枚舉類型分為兩種:
1.enum class,它的枚舉值名字位于enum的局部作用域內(nèi),枚舉值不會隱式地轉(zhuǎn)換成其他類型。
2.普通的enum,它的枚舉值名字與枚舉類型本身位于同一個作用域中,枚舉值隱式地轉(zhuǎn)換成整數(shù)。
普通枚舉和類枚舉最顯著地差異是“作用域”不同和“隱式類型轉(zhuǎn)換”,接下來我們分開講。
1.作用域
枚舉類
枚舉名字前面帶class修飾符地枚舉就是枚舉類,它地成員作用域在enum內(nèi)部,外部是不能直接訪問的,需要通過類名::訪問。舉一個例子:
enum class Lights{ red,green,yellow };
你在類外面直接訪問red或其它任何元素都是不行的,正確的訪問方式是:
Lights::red
和類訪問公有成員是一樣的。
普通枚舉
普通枚舉就是不帶class修飾符的枚舉,它的枚舉值名字與枚舉類型本身位于同一個作用域中。不需要通過名字訪問,舉個例子:
enum Lights{ red, green,yellow };
訪問方式和類枚舉也有顯著差別,直接使用枚舉值名字就行了。
red //或 Lights::red;
和在函數(shù)里訪問一個局部變量是一樣的,不需要顯式指定枚舉名字,也可以顯式指定枚舉名字,效果一樣的。
未命名枚舉
還有一種枚舉就是既不加class修飾,也不寫枚舉名字,而是只有枚舉值,例如:
enum{red,green,yellow};
這種枚舉訪問方式和普通枚舉一樣,就是少了一個枚舉名訪問方式(因為沒有名字,所以沒法用名字訪問)。
red
2.隱式類型轉(zhuǎn)換
枚舉常用一些整數(shù)類型表示,每個枚舉值是一個整數(shù)。如果不顯式指定枚舉值,那么枚舉值是默認從0開始的正整數(shù)。這一點對于所有的枚舉類型都是一樣的。
//枚舉類 enum class Lights{ red,// 0 green,// 1 yellow// 2 }; //普通枚舉 enum Lights{ red,// 0 green,// 1 yellow// 2 }; //未命名枚舉 enum { red,// 0 green,// 1 yellow// 2 };
不同的是使用class修飾的枚舉類型,它的枚舉值是不能隱式轉(zhuǎn)換成其他類型的(這里是int)。比如:
//枚舉類 int ecl = Lights::red;//這是錯誤的 //普通枚舉 int el = Lights::red;//這是正確的 //未命名枚舉 int l = red;//這是正確的
3.顯式指定枚舉值類型
如果我們不顯式指定枚舉值類型,那么枚舉值默認是帶符號或無符號的整型。我們也可以顯式指定枚舉值類型為char或其他類型,例如:
enum class Lights:int{red,green,yellow};//sizeof(Lights) == 4 enum class Lights:char{red,green,yellow};//sizeof(Lights) == 1
4.指定枚舉值的值
前面我們知道如果不顯式指定枚舉值的話,默認是int,而且值是從0開始的依次往后排的。也就是,第一個值是0,第二個是1,第三個是2…
enum class Lights{ red = 0, green = 1, yellow = 2 };
上面的效果和默認值是一樣的。
還有一種方法是可以給枚舉值指定負數(shù),比如-1,考慮下面的代碼:
enum class Lights{ red = -1, green, yellow };
需要注意的是,上面red指定為-1,green沒有指定值,那么green就是默認0,yellow就是1,依次遞增。
不過這種命名方式多少有點不符合常理了,雖然語法上沒有錯,編譯也不會報錯,但是不建議這么用。就維持默認就行了。
4.整形顯式轉(zhuǎn)換成枚舉
一個整數(shù)類型的值可以顯式地轉(zhuǎn)換成枚舉類型。如果這個值屬于枚舉的基礎(chǔ)類型的取值范圍,則轉(zhuǎn)換是有效的;否則,如果超出了合理的表示范圍,則轉(zhuǎn)換的結(jié)果是未定義的??紤]下面的例子:
enum class Flag:char {x =1,y =2,z =4,e=8,f=127,g=128}; Flag flag4 = static_cast<Flag>(5); Flag flag5 = static_cast<Flag>(999);
char的取值范圍是-128-127,f=127的值是沒問題的,但是g=128的值會引發(fā)窄化轉(zhuǎn)換錯誤,從而導(dǎo)致編譯報錯。
再看下面的兩個,雖然編譯器不報錯,但是5不是枚舉里面的值,這么做失去意義;999嚴重超過char的取值范圍,但是不會觸發(fā)窄化轉(zhuǎn)換的錯誤,導(dǎo)致未定義的行為。
總結(jié)
1.枚舉值的默認值是有規(guī)律的,如果不能滿足你的需求,就自定義值
2.建議使用枚舉類,副作用比較小。主要是名字空間污染的問題,可能一不小心就會引發(fā)其他的問題。
到此這篇關(guān)于解讀C++中枚舉(enum)的使用的文章就介紹到這了,更多相關(guān)C++枚舉內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談C語言中strcpy,strcmp,strlen,strcat函數(shù)原型
下面小編就為大家?guī)硪黄獪\談C語言中strcpy,strcmp,strlen,strcat函數(shù)原型。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04VC++?2019?"const?char*"類型的實參與"LPCTSTR"
這篇文章主要給大家介紹了關(guān)于VC++?2019?"const?char*"類型的實參與"LPCTSTR"類型的形參不兼容的解決方法,文中通過圖文介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2023-03-03C++基礎(chǔ)入門教程(二):數(shù)據(jù)、變量、宏等
這篇文章主要介紹了C++基礎(chǔ)入門教程(二):數(shù)據(jù)、變量、宏等,本文講解了變量初始化、宏定義、三種進制數(shù)的表示、const初探、auto聲明等內(nèi)容,需要的朋友可以參考下2014-11-11Win32應(yīng)用程序(SDK)設(shè)計原理詳解
這篇文章主要介紹了Win32應(yīng)用程序(SDK)設(shè)計原理,對于理解win32應(yīng)用程序運行原理有很大的幫助,需要的朋友可以參考下2014-08-08