C ++ 11 兩種改進得資料型別,空指標與強型別列舉

C ++ 11 兩種改進得資料型別,空指標與強型別列舉

更多C++11內容,或者C++學習資料私信我 “程式碼”即可獲取

雖說C++現在17了,但是還是講下C++11中兩個型別吧,C ++從一開始就嘗試改進C的型別系統,新增類可以構建更好的型別和列舉的類,這樣就不需要預處理器的某些用途(這在型別上並不安全)。C ++還為您執行更少的隱式型別轉換(例如不允許從void *進行隱式賦值),讓編譯器為您找到更多錯誤。C ++ 11更進一步,即使列舉擺脫了整數#define常量的需要,我們仍然有醜陋的,輸入不良的NULL指標。

C ++ 11透過新增一個具有自己型別的顯式,清晰的nullptr值來清除這一點。C ++ 11還帶來了新的強型別列舉。在本文中,我將介紹這些改進。

為什麼我們需要強型別列舉?

C ++ 11 兩種改進得資料型別,空指標與強型別列舉

更多C++11內容,或者C++學習資料私信我 “程式碼”即可獲取

1.那麼為什麼我們還需要強型別的列舉?

舊式C ++列舉基本上是整數; 它們可以與整數或其他不同型別的列舉進行比較。問題是,你通常不想這樣做,因為列舉應該是一些固定的列舉值列表。

2.為什麼要與其他列舉型別(或整數)進行比較?

這就像說,“請把這種指甲與這種牙刷比較。” 這沒有任何意義,你可能並不是故意這樣做。但舊式的C ++列舉會很高興地告訴你,“為什麼是,這個指甲不像這個牙刷”,或者更糟糕的是,它們可能比較相同,因為它們碰巧共享相同的基本整數值(“啊是的,這個指甲是電子牙刷“)。現在,使用強型別列舉,編譯器會告訴您正在執行此操作。如果你真的是這個意思。另一個限制是列舉值是無範圍的 - 換句話說,您不能有兩個共享相同名稱的列舉:

C ++ 11 兩種改進得資料型別,空指標與強型別列舉

更多C++11內容,或者C++學習資料私信我 “程式碼”即可獲取

強型別列舉

強型別列舉是一種新的列舉,宣告如下:

C ++ 11 兩種改進得資料型別,空指標與強型別列舉

更多C++11內容,或者C++學習資料私信我 “程式碼”即可獲取

使用單詞class意味著每個列舉型別確實不同,並且與其他列舉型別不可比。強型別列舉,列舉類,也有更好的範圍。每個列舉值都在enum類的名稱範圍內。換句話說,要訪問列舉值,您必須寫:

C ++ 11 兩種改進得資料型別,空指標與強型別列舉

更多C++11內容,或者C++學習資料私信我 “程式碼”即可獲取

舊式C ++列舉仍然可用, 如果您需要它們, 主要是為了與現有程式碼庫向後相容,他們確實拿起了一招; 你現在可以選擇將列舉名稱放在值的前面:Color :: RED。但由於這是可選的,因此無法解決任何命名衝突; 它只是讓它更清晰一點。

與舊式列舉相比,列舉類具有另一個優點。您

可以向強型別列舉進行前向宣告,這意味著您可以編寫如下程式碼

C ++ 11 兩種改進得資料型別,空指標與強型別列舉

更多C++11內容,或者C++學習資料私信我 “程式碼”即可獲取

為什麼這會有用?前向宣告通常是關於磁碟上程式碼的物理佈局到不同檔案中,或者提供不透明物件作為API的一部分。在第一種情況下,您關心物理磁碟佈局,

使用轉發宣告允許您在將特定值放入cpp檔案時在標頭檔案中宣告列舉型別。這使您可以非常頻繁地更改可能的列舉值列表,而無需強制重新編譯所有相關檔案。在第二種情況下,列舉類可以作為型別安全公開,但從一個API函式返回的其他不透明值將傳遞到另一個API函式。使用API的程式碼不需要知道型別可以採用的可能值。由於編譯器仍然知道型別

明確定義的列舉大小

列舉類的最後一個優點是

可以設定列舉的大小 - 您可以使用任何有符號或無符號整數型別

它預設為int,但您也可以使用char,unsigned long等

。這將確保編譯器之間的相容性。

enum class Colors : char { RED = 1, GREEN = 2, BLUE = 3 };

但是在C ++ 11中,我們可以做得更好,

使用cstdint指定列舉的確切大小

C ++遇到的一個問題是缺乏提供固定的,定義明確的大小的標準型別。例如,有時您希望擁有一個32位整數,而不僅僅是一個在不同體系結構上可能具有不同大小的int。在C ++ 11中,C99標頭檔案stdint。h已作為cstdint包含在內。

cstdint頭包括諸如std :: int8_t,std :: int16_t,std :: int32_t和std :: int64_t之類的型別(以及以u:std :: uint8_t開頭的無符號版本)。

下面是一個將這些新型別與列舉類組合在一起的示例,以便在編譯器和體系結構中獲得完全已知的列舉大小:

#include <cstdint>

enum class Colors : std::int8_t { RED = 1, GREEN = 2, BLUE = 3 };

空指標

C ++ 11 兩種改進得資料型別,空指標與強型別列舉

更多C++11內容,或者C++學習資料私信我 “程式碼”即可獲取

在C和C ++中,表達NULL指標的想法總是很重要 - 一個沒有值的指標。奇怪的是,在C ++中,使用的表示式0(或NULL,總是#defined為零)甚至不是指標型別。儘管這在大多數情況下起作用,但它可能導致奇怪和意想不到的問題,不可否認的是,邊緣情況。例如,假設您有以下兩個函式宣告:

void func(int n);

void func(char *s);

func( NULL ); // 會呼叫那一個?

雖然看起來第二個函式將被呼叫 - 畢竟,你傳遞的似乎是一個指標 - 它實際上是第一個被呼叫的函式!麻煩的是因為NULL是0,而0是一個整數,所以將呼叫第一個版本的func。這是一種事情,是的,它不會一直髮生,但是當它確實發生時,是非常令人沮喪和困惑的。如果您不知道發生了什麼的細節,它可能看起來像編譯器錯誤。看起來像編譯器錯誤的語言功能,不是你想要的。

輸入nullptr。在C ++ 11中,nullptr是一個新的關鍵字,可以(並且應該!)用於表示NULL指標; 換句話說,無論你以前寫過NULL,都應該使用nullptr。對於程式設計師來說,你不再清楚(每個人都知道NULL意味著什麼),但它對編譯器來說更加明確,當用作指標時,編譯器不會再看到任何地方被用來具有特殊含義的0。

順便說一下,nullptr不僅被宣告為指標並且隱式轉換為所有指標型別(和bool)

,但它是它自己特殊的,不同的型別:

decltype( nullptr )

雖然我們可以使用decltype來提取其型別,但還有一個更方便的表示法:

std::nullptr_t

由於nullptr是它自己的唯一型別,因此當您想要確保只為值獲取空指標時,可以將它用作建構函式或函式引數。例如:

void func( std::nullptr_t );

宣告一個只接受nullptr(或者一個值轉換為std :: nullptr_t)的函式,而不是其他任何東西,

一個相當巧妙的技巧

C ++ 11 兩種改進得資料型別,空指標與強型別列舉

更多C++11內容,或者C++學習資料私信我 “程式碼”即可獲取

更多精彩

這貨不是在講連結串列,而是講的是C語言連結串列與檔案的學生管理系統

C語言完整簡單專案之 C語言多關卡推箱子實戰影片教學