現代C 風格的新元素

2021-06-01 19:34:40 字數 2784 閱讀 4737

「c++11就像一門新的語言。」 – bjarne stroustrup

這些特性改變了編寫c++程式使用的**風格和習語[todo],通常也包括你設計c++函式庫的方式。例如,你會看到更多引數和返回值型別為智慧型指標(smart pointer),同時也會看到函式通過值傳遞返回大型物件

你將會發現在大多數的**示例中充斥著新特性的身影。例如,幾乎每5行現代c++**示例都會使用到auto

c++11的其他特性也很棒。但是請先熟悉下面這些,正是因為這些特性的廣泛使用使得c++11**如同其他現代主流語言一樣整潔、安全和高效,與此同時保持了c++傳統的效能優勢。

本文會不斷更新,主要變更及內容增加請參見文末變更記錄

auto

基於以下兩個原因,盡可能使用auto:首先,使用auto會避免重複宣告編譯器已經知道的型別。

//

c++98

map::iterator i = m.begin ();

//c++11

auto i = begin (m);

其次,當使用未知型別或者型別名稱不易理解時使auto會更加便利,例如大多數的lambda函式[todo]——你甚至不能簡單的拼寫出型別的名字。

//

c++98

binder2nd< greater > x = bind2nd ( greater(), 42 );

//c++11

auto x = (int i) ;

需要注意,使用auto並不改變**的含義。**仍然是靜態型別[譯註],每個表示式的型別都是清晰和明確的;c++11只是不需要我們重複宣告型別的名字。一些人剛開始可能會害怕在這裡使用auto,因為感覺好像沒有(重複)宣告我們需要的型別就意味著會碰巧得到乙個不同的型別。如果你想要明確地進行一次強制型別轉換,沒有問題,宣告目標型別就好了。然而大多數情況下,只要使用auto就可以了;幾乎不會出現錯誤地拿到乙個不同型別的情況,即便出現錯誤,c++的強靜態型別系統也會由編譯器讓你知道這個錯誤,因為你正試圖訪問乙個變數沒有的成員函式或是錯誤地呼叫了該函式。

譯註:動態型別語言(dynamic typing language)是指型別檢查發生在執行期間(run-time)的語言。靜態型別語言(static typing language)是型別檢查發生在編譯期間(compile-time)的語言。

智慧型指標:無須delete

請始終使用標準智慧型指標以及非占有原始指標(non-owning raw pointer)。絕不要使用占有原生指標(owning raw pointer)和delete操作,除非在實現你自己的底層資料結構這種少見的情況下(即使在此時也需要在 class 範圍內保持完好的封裝)。如果只能夠知道你是另乙個物件唯一的所有者,請使用unique_ptr來表示唯一所有權(todo)。乙個」new t」表示式會馬上初始化另乙個引用它的物件,通常是乙個unique_ptr。

//

c++11 pimpl idiom

class widget );

想要使用c++編寫乙個迴圈或者類似的新特性?不用著急;只要編寫乙個模板函式(template function)(函式庫演算法),並且幾乎可以將lambda當做語言特性來使用,與此同時會更加靈活,因為它不是固定的語言特性而是乙個真正的函式庫。

//

c#lock( mut_x )

lock( mut_x, [&]{

... use x ...

去熟悉lambda吧。你會大量使用它,不僅僅在c++中——它已經廣泛應用於很多主流的程式語言。乙個開始的好去處請參考我在pdc2010的演講《無處不在的 lambda》

move / &&

move被認為是copy的最佳優化,儘管它也使得其他事情成為可能比如資訊被**。

//

c++98:避免 copy 的替代方法

vector* make_big_vector (); //

選擇1: 返回指標: 沒有拷貝,但不要忘記 delete

vector* result = make_big_vector ();

void make_big_vector ( vector& out ); //

選擇2: 通過引用傳遞: 沒有拷貝,但是呼叫者需要傳入乙個有名物件

vector result;

make_big_vector ( result );

//c++11: move

vector make_big_vector (); //

通常對於」被呼叫者(callee)分配的空間「也適用

vector result = make_big_vector ();

move語法改變了我們設計api的方式。我們可以更多地設計通過值傳遞。為你的型別啟用move語法,使用時會比copy更有效。

更多變化

還有更多現代c++的特性。並且我計畫在未來編寫更多深入c++11新特性以及其他特性的短文,我們會知道更多並且喜歡上它。

但目前,這是必須知道的新特性。這些特性組成了現代c++風格的核心,使得c++**看起來和執行時像他們設計的那樣,你將會看到這些特性會出現在幾乎每一段你看到或者編寫的現代c++**中。並且它們使得現代c++更加乾淨、安全且快速,使得c++在未來的若干年仍然是我們產業的依靠。

主要變更

2011-10-30:為lambda增加c#lock示例。重新組織智慧型指標首先介紹unique_prt。

C 陣列動態新增新元素的 方法

陣列的長度 不是固定的,而c 陣列 是不允許動態新增新的元素的.如何動態新增進陣列呢?這時候我們要借助 list 看如下 string ktcodes new string 0 機型逗號拆分 listktls ktcodes.tolist ktls.add svktcode ktcodes ktls...

為新新增的新元素繫結新事件

在按鈕前方插入 option option value behind 在按鈕後方插入 option select br div id container button id add new el 新增新元素 button br button id add new ev 為其繫結事件 button d...

ie7下table新增新元素的bug

有時候我們需要新建立乙個新的元素 var a document.createelement div a.setattribute class class a.setattribute style width 530px 這樣看不出效果,在ie7下有時候是沒有樣式的,a addclass class ...