溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++11強類型枚舉是什么

發(fā)布時間:2020-08-15 11:34:39 來源:億速云 閱讀:136 作者:小新 欄目:開發(fā)技術

這篇文章主要介紹了C++11強類型枚舉是什么,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。

1.傳統(tǒng)枚舉類型的缺陷

枚舉類型是C/C++中用戶自定義的構造類型,它是由用戶定義的若干枚舉常量的集合。枚舉值對應整型數值,默認從0開始。比如定義一個描述性別的枚舉類型。

enum Gender{Male,Female};

其中枚舉值Male被編譯器默認賦值為0,F(xiàn)emale賦值為1。傳統(tǒng)枚舉類型在設計上會存在以下幾個問題。

(1)同作用域同名枚舉值會報重定義錯誤。傳統(tǒng)C++中枚舉常量被暴漏在同一層作用域中,如果同一作用域下有兩個不同的枚舉類型,但含有同名的枚舉常量也是會報編譯錯誤的,比如:

enum Fruits{Apple,Tomato,Orange};
enum Vegetables{Cucumber,Tomato,Pepper}; //編譯報Tomato重定義錯誤

其中水果和蔬菜兩個枚舉類型中包含同名的Tomato枚舉常量會導致編譯錯誤。因為enum則是非強作用域類型,枚舉常量可以直接訪問,這種訪問方式與C++中具名的namespace、class/struct以及union必須通過"名字::成員名"的訪問方式大相徑庭。

(2)由于枚舉類型被設計為常量數值的“別名”,所以枚舉常量總是可以被隱式轉換為整型,且用戶無法為枚舉常量定義類型。

(3)枚舉常量占用存儲空間以及符號性不確定。C++標準規(guī)定C++枚舉所基于的“基礎類型”是由編譯器來具體實現(xiàn),這會導致枚舉類型成員的基本類型存在不確定性問題,尤其是符號性問題,即??疾烊缦率纠?/p>

enum A{A1=1,A2=2,ABig=0xFFFFFFFFU};
enum B{B1=1,B2=2,BBig=0xFFFFFFFFFUL};

int main()
{
	cout<<sizeof(A1)<<endl;	//4
	cout<<ABig<<endl;		//4294967295
	cout<<sizeof(B1)<<endl;	//8
	cout<<BBig<<endl;		//68719476735
}

以上輸出結果是在Linux平臺下使用g++編譯輸出的結果,在VC++(VS2017)中的輸出結果分別是4、-1、4和-1??梢姴煌幾g器對枚舉常量的整型類型的寬度和符號有著不同的實現(xiàn)。GNU C++會根據枚舉數值的類型使用不同寬度和符號的整型,VC++則始終以有符號int來表示枚舉常量。

為了解決以上傳統(tǒng)枚舉類型的缺陷,C++11引入了強類型枚舉解決了這些問題。

2.強類型枚舉

非強作用域類型,允許隱式轉換為整型,枚舉常量占用存儲空間以及符號性的不確定,都是枚舉類缺點。針對這些缺點,C++11引入了一種新的枚舉類型——強類型枚舉(strong-typed enum)。

強類型枚舉使用enum class語法來聲明:

enum class Enumeration{VAL1,VAL2,VAL3=100,VAL4};

強類型枚舉具有如下幾個優(yōu)點:
(1)強作用域,強類型枚舉成員的名稱不會被輸出到其父作用域,所以不同枚舉類型定義同名枚舉成員編譯不會報重定義錯誤。進而使用枚舉類型的枚舉成員時,必須指明所屬范圍,比如Enum::VAL1,而單獨的VAL1則不再具有意義;
(2)轉換限制,強類型枚舉成員的值不可以與整型發(fā)生隱式相互轉換。比如比如Enumeration::VAL4==10;會觸發(fā)編譯錯誤;
(3)可以指定底層類型。強類型枚舉默認的底層類型是int,但也可以顯示地指定底層類型。具體方法是在枚舉名稱后面加上":type",其中type可以是除wchar_t以外的任何整型。比如:

enum class Type:char{Low,Middle,High};

注意:
(1)聲明強類型枚舉的時候,既可以使用關鍵字enum class,也可以使用enum struct。事實上,enum struct與enum class在語法上沒有任何區(qū)別。
(2)由于強類型枚舉是強類型作用域的,故匿名的enum class可能什么都做不了,如下代碼會報編譯錯誤:

enum class{General,Light,Medium,Heavy}weapon;
int main()
{
weapon=Medium; //編譯出錯
bool b=weapon == weapon::Medium; //編譯出錯
return 0;
}

當然對于匿名強類型枚舉我們還是可以使用decltype來獲得其類型并進而使用,但是這樣做可能違背強類型枚舉進行匿名的初衷。

3.C++11對傳統(tǒng)枚舉類型的擴展

傳統(tǒng)枚舉類型為了配合C++11引入的強類型枚舉,C++11對傳統(tǒng)枚舉類型進行了擴展。
(1)底層的基本類型可以在枚舉名稱后加上":type",其中type可以是除wchar_t以外的任何整型,比如:

enum Type:char{Low,Middle,High};

(2)C++11中,枚舉類型的成員可以在枚舉類型的作用域內有效。比如:

enum Type{Low, Middle, High };
Type type1 = Middle;
Type type2 = Type::Middle;

其中Middle與Type::Middle都是合法的使用形式。

感謝你能夠認真閱讀完這篇文章,希望小編分享C++11強類型枚舉是什么內容對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業(yè)資訊頻道,遇到問題就找億速云,詳細的解決方法等著你來學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI