c++11新標準

2020-08-12 08:20:08

說起C++語言,它現在被公認爲是在各種程式語言中最難學的語言之一,它的語法知識點之廣泛,細節內容之多,學習難度之大,時間週期之長,都使得人們對這門語言「敬而遠之」。然而C++語言又具有不可替代的巨大優勢。

主要的優勢有以下幾點,首先C++是一個嚴謹,精確的語言。它的標準定義非常明確,語言結構層次分明,清晰順暢,具有優秀的程式語言應該具有的品質。

其次,C++語言支援對底層的操作,這是又一大優勢。支援底層操作意味着程式設計的效率將顯著提升。C++語言在繼承c語言的基礎上,改進了自己對底層的支援,這令其更加有吸引力。

第三,C++語言完全相容c語言,這使得人們可以按照傳統C的程序導向式的程式設計,這對於實現底層和內核操作無疑是一大亮點。

第四,C++語言是物件導向程式設計的程式語言,它不僅僅是對c語言的擴充,它在物件導向方面新增了模板,STL,以及各類容器,使得它更加適合大型軟體工程的開發和創新。另外,C++所獨有的模板超程式設計的能力也是它繼續保持生命力的關鍵所在。最後,C++語言具有極高的效能,這是C++語言衆多優勢中的核心,這種優勢使它廣泛應用於大型伺服器程式設計,遊戲開發,雲端計算等高階技術領域。如今,C++語言仍然應用在各個領域,在11月的TIOBE程式語言排行榜中,C++語言仍然穩居前三,這是對C++語言優勢最好的證明。

C++語言是在不斷髮展和改進的,正如C++之父本賈尼所說,c++好像是一種全新的程式語言。C++11是C++程式設計語言標準的一個新的版本,在2011年由ISO批準併發布。C++11新標準從而代替了原來的C++98和C++03.。C++11標準是對C++的一次巨大的改進和擴充。在覈心語法,STL標準模板等方面增加衆多新功能,新亮點。例如新增auto,deltype,nullptr等關鍵字,增加範圍for回圈,新增lambda表達式等。下面 下麪將對C++增加的衆多新特性進行總結。

(一)auto關鍵字

C++11新標準成功引入了auto關鍵字,auto關鍵字可以幫助我們分析表達式所屬的型別。和以前的一些型別說明符明顯不同的是,auto關鍵字可以讓編譯器自動分析某個初始值來判斷它所屬的型別。當然,使用auto關鍵字必須確定初始值。

圖片1

如圖1所示,我們定義了一個變數a,它的初始值是一個make_share型別。這樣我們就新建了一個指向string的智慧指針shared_ptr;相比之前的C++標準,這樣將會更加簡便,利於我們快速完成程式設計。

(二)decltype關鍵字

C++11新標準引入了又一種型別說明符decltype,它的功能是選擇並返回運算元的數據型別。它會使得編譯器自動分析表達式的型別並得到它的型別,最關鍵是它不會去計算表達式的值。例如圖2所示:

圖片2

我們定義了一個常數b,它的初值是10,又定義了一個值爲20的變數c,然後通過decltype關鍵字定義了兩個變數x,y。讓編譯器通過推斷括號裡的表達式來判斷x,y的型別。我們很容易得出b的型別是const int,而c的型別是int。

(三)字面值nullptr

我們都知道所謂空指針就是不指向任何物件的指針,定義空指針的辦法有很多。例如將這個指針的初值設爲0,或者將它的初值設爲NULL,在標準庫iostream中,NULL代表的就是0.

而C++11新標準引入了一個新的字面值來初始化空指針,它就是nullptr,nullptr是一個比較特殊的字面值,它可以任意轉換成其他的任意指針型別。例如圖3所示:

圖片3

如圖3所示,我們定義了一個指向int的指針p,且把它用字面值nullptr初始化,隨後定義了一個指向動態記憶體的指針q,然後將q所指向的動態記憶體地址賦給p,現在p就指向了那個地址,我們釋放q。

(四)constexpr關鍵字

C++新標準引入constexpr關鍵字,它許可將變數宣告爲constexpr來由編譯器驗證變數是否是一個常數表達式。當然,宣告爲constexpr的變數一定是一個常數表達式。而且需要用長量表達式初始化。例如:

圖片4

如圖4所示。我們定義了常數val,並給它賦予了初值,然後用val+1來初始化另外一個常數val2.這裏要說明的是如果肯定一個變數是常數表達式,我們就可以把它宣告爲constexpr型別。

(五)範圍for語句

範圍for語句是c++11新標準一個重要的參照,這種遍歷語句遍歷指定序列的每個元素,並且可以對每個元素進行某種操作。它的語法格式是:

For(declaration : expression)
statement;

其中,declaration是一個變數,它用於表示一個原子元素或者基礎元素,而expression是一個物件或者是一個序列,是被遍歷的物件。這個物件將被存取裏面的原子元素。存取一個元素之後,將會被推進至下一個需要被存取的值。例如圖5所示:

圖片5

如圖5所示。我們定義了一個vector容器ivec,並且對它進行了列表初始化(列表初始化也是c++11新標準引入的),運用範圍for回圈,遍歷ivec容器裏面的元素,這裏的c可被編譯器推斷爲string型別,auto關鍵字的作用前面已說明,不在詳述。我們每遍歷一個容器中的元素就將它賦值爲「b」,然後將它輸出,這也證明了可用範圍for語句對容器或者物件中的基礎元素進行指定操作。

(六)Lambda表達式

C++11新標準新增的一項重要功能就是lambda表達式,所謂lambda就是表示一個可呼叫的程式碼單元,也可以說是一個可呼叫物件,還可以理解爲一個沒有命名的行內函式。Lambda的組成結構與函數很相似,它擁有一個返回型別,一個形參列表,一個函數體。Lambda也可以定義在函數內部。它的組成結構如下:

 

[capture list] (parameter list) -> return type { function body}

Capture list 表示捕獲列表,也就是lambda所在函數中的區域性變數的列表,如果沒有,則這個列表爲空。Return type 表示該lambda的返回型別,Parameter list 爲形參列表,Function body是函數體,這些和函數表示是一樣的。需要注意的是,如果有返回型別,lambda必須使用尾置返回來確定型別。另外,lambda必須包括捕獲列表和函數體。另外的幾個可以省略。例如:

圖片6

如圖6所示。我們定義了一個名爲fcn的lambda表達式。它只有捕獲列表和函數體。這個lambda表達式返回值爲1.之後。我們呼叫這個lambda,會輸出1。

(七)initializer_list

Initializer_list定義在c++11新標準新引入的initializer_list標頭檔案中。Initializer_list也是一種標準庫型別。此型別用於存取c++初始化列表中的值,列表中的元素型別爲const的,也就是常數,我們無法改變initializer_list中的元素的值。這種型別的物件由編譯器從初始化列表宣告中直接自動構造,所謂初始化列表宣告就是被包括在花括號裏面的,用逗號分隔元素的列表。Initializer_list可以用於表示某種特定型別的值的陣列。

 

圖片7

 

如圖7所示,我們定義了一個名爲mylist的類,它有一個initializer_list型別的建構函式,此建構函式將傳遞進來的initializer_list的型別參數中的值存入str中,並以空格分隔。

(八)標準庫bind函數

C++11引入了新的標準庫函數bind,我們可以將bind看成一個函數適配器。它的組成結構如下:

Auto newcallable = bind(callable,arg_list)

Newcallable表示一個新的可呼叫物件,arg_list表示參數列表,這個參數也就是callable所對應的的參數。當我們呼叫newcallable時,newcallable會呼叫callable,並且把arg_list中的參數傳遞給callable。對於arg_list,這個燦叔列表可能是具有實際值得參數,也可能是像_n這樣的佔位符。這個佔位符表示newcallable的參數。比如_1就是newcallable的第一個參數,_2就是newcallable的第二個參數。以此類推。如圖8:

圖片8

在圖8中,我們定義了一個名爲myfun的類。它有3個成員,分別是a,b兩個int型的成員,和一個有加法功能的成員函數。注意,我們的佔位符是定義在std名稱空間中的placeholders中。首先定義了一個名爲fcn的新呼叫物件,隨後我們呼叫標準庫函數bind。它的呼叫物件,也就是它的第一個參數是成員函數add_num,我們把參數1,3,傳遞給這個成員函數。最後,我們呼叫fcn這個可呼叫物件。得到結果4.

 

我們再定義了一個名爲fcn2的可呼叫物件,它同樣以myfun作爲可呼叫參數。我們這裏使用了佔位符,它表示fcn2具有一個參數。當我呼叫fcn2時,我們將這兩個參數傳遞給myfun。隨後輸出結果。

(九)智慧指針shared_ptr,unique_ptr

新的C++11標準庫爲了更好地管理和使用動態記憶體,防止記憶體漏失和懸垂指針,定義了兩個智慧指針型別,分別是shared_ptr和unique_ptr。它們均定義在標頭檔案memory中。Shared_ptr可以讓多個智慧指針指向同一個物件,而unique_ptr只容許一個指針獨自指向一個物件。下面 下麪詳細說明這兩個智慧指針。

Shared_ptr是用於管理動態記憶體的指針,它擁有垃圾回收機制 機製。可與其他物件共用管理,這種指針具有取得指針所有權並共用該所有權的能力。當最後一個指針釋放所有權時,也就是參照計數爲0時,指針的所有者將刪除該指針。Shared_ptr自身如果被銷燬,或者通過賦值或者通過呼叫reset函數,他們的值被改變的話,它就釋放對共用物件的所有權。

Unique_ptr擁有它所指向的物件,它與shared_ptr不同點是,在任一時刻,只能有一個unique_ptr指向一個物件。如果這個unique_ptr被銷燬,則它所指向的物件也要被銷燬。
例如:

圖片9.

如圖9所示,我們定義了5個智慧指針,首先定義的ptr是一個shared_ptr型別,他通過使用make_shared來初始化。之後的4個指針都是unique_ptr,其中,ptr4是一個管理動態int物件的指針,ptr3接管了ptr4所指向的物件。在語句中。我們看到ptr4呼叫release函數解除自己對所指物件的所有權,並將它賦給ptr3.ptr5同樣的道理。通過呼叫reset函數。釋放它原來擁有的物件,接管ptr3所指的物件。

(十)右值參照

C++11標準庫引入了右值參照,這是一種全新的參照型別,之所以稱爲右值參照,因爲它就是必須系結在右值的參照上。右值參照的符號是&&,而不是&。右值參照擁有一條關鍵的性質。那就是它只能系結在一個將要銷燬的物件上。所以它更加方便移動操作。

我們可以將右值參照進行分類。首先一類右值參照是將亡值,也就是馬上要銷燬的值,一般指的是跟右值參照相關的表達式,這樣的表達式是要被銷燬的物件。另外一類是純右值,

例如按值返回的臨時物件,運算表達式產生的臨時物件,原始字面值,lambda等。

上述總結了C++11十大典型的新特性。通過對c++11新特性的應用,可以更好地理解和掌握c++語言。C++11還有很多新特性,在此不再舉例詳述。具體請參考《C++ primer 5》,《深入理解C++11》,《深入探索c++物件模型》。


鏈接:https://www.jianshu.com/p/052865fd3478