1. 程式人生 > >c++11新特性總結和boost庫的使用

c++11新特性總結和boost庫的使用

來自<<深入理解c++11 c++11新特性解析與應用>>

程式碼見:https://github.com/Jeromecen/cpp11study/tree/master

I、保持語言的穩定性和相容性” 總結:主要是utf8字串,虛擬函式override/final支援。 1、c++11巨集和型別(考慮和c99相容):STDC_HOSTEDSTDC、__VA_ARGS__巨集可以替代...、__cplusplus巨集用於c和c++混編,非布林值還可以判斷是否支援c++ 11;_Pragma操作符。 long long 64bit型別, static_assert用於編譯時警告,表示式必須是常量。string都是utf-8型別的,可以和utf-16,char*等轉換。可用sizeof(類::非靜態成員)獲取成員大小。 2、面嚮物件語言特性完善:虛擬函式override/final支援;增加非靜態成員變數就地初始化=和{}符號;noexcept函式宣告沒有異常丟擲,如果丟擲了則用std::terminate()來終止程式; 3、完善拓展模板語法:friend FriendClass就可以宣告友元,模板中也可使用;模板函式也支援了預設引數;顯式模板例項化和外部模板宣告優化連結;匿名和區域性的類/結構體等,都可以作為模板實參。

II、“通用為本,專用為末” 總結:主要是右值引用,移動語義,完美轉發的引入。 1、對效能的更加關注,和C高效相容:引入右值引用型別,函式模板完美轉發實現;和C語言的相容,pod型別的定義;聯合體的拓展。 2、面向物件編寫要更加高效和簡單:移動建構函式,移動語義;繼承建構函式和建構函式委派; explict拓展到型別轉換函式;型別初始化列表的支援。 3、完善拓展泛型程式設計語法:inline名字空間允許父空間中對模板重定義;using別名可以用於模板和例項化模板;例項化模板時對SFINAE原則拓展,允許模板引數中存在非例項化的表示式存在。

III、“易學易用” 總結:主要是是型別推導規則引入,for自動範圍和迭代引入。 1、基礎符號編譯器增強:1).>>避免模板或型別轉換中需新增額外的空格。2).for(auto &e: containerObj){}自動範圍和迭代語句,陣列和STL容器都支援(stl中e是元素型別),自定義容器需過載。 2、新增了型別推導規則: 1).auto編譯期型別多用於函式或表示式內部的變數,不能用於函式引數,類成員,陣列和模板例項化中(雖然提供值),可以用於初始化列表和new物件中。會去掉volatile和const修飾符。 2).decltype是最靈活的編譯期型別,根據表示式而不是隻推導型別,可以用在所有表示式型別確定的地方(函式返回值是不確定的),可以帶走volatile和const修飾符。左值判斷技巧。 auto可以減少程式碼量,decltype可以更靈活的獲得表示式運算後的型別,他們都有型別自適應性(值修改後型別不用變),可以多用於庫相關程式碼的編寫。業務邏輯用確定型別會清晰些。 3、追蹤返回型別,auto和decltype的結合,auto Sum(T1 &t1, T2 &t2) -> decltype(t1+t2) { return t1+t2}能確定運算後變化的型別,增強函式和函式指標泛型能力。

IV 、“提高型別安全" 總結: 1、新列舉型別:新增了enum class enumName:type{}作用域限定符和型別。 2、智慧指標:unique_ptr用在單模組內使用,shared_ptr和weak_ptr用引用計數在多個模組間共享。記得初始化;判是否有效,*和->使用,需轉換為原指標迭代跳轉;move或reset後要小心使用。 3、GC: 標記-清除GC實現,現在暫時定義了介面,原因是指標的太靈活(指標任意在記憶體中跳轉)導致隱藏指標,GC會誤刪,用declare_reachable等標記隱藏指標解決,且delete和回收是相容的。

V、"提高效能及其操作硬體的能力“ 總結: 1、1)constexpr是編譯期常量,constexpr超程式設計的引入;2)變長引數模板類和函式模板,庫編寫用簡單例項思維解決,非庫編寫者用tuple和容器的emplace系列函式即可。超程式設計對庫程式設計師是一種簡化,而不是複雜化。 2、並行程式設計: 1)原子型別:atomic定義基本型別,自定義型別用_Atomic實現(現在還不支援),原子型別是編譯器用了系統底層的匯流排鎖或儲存鎖加快鎖定,其它同時訪問執行緒會被阻塞,atomic_flag自旋無鎖同步,memory_order對弱順序程式碼執行記憶體模型調優,是cpp11並行程式設計中的一大亮點。 2).多執行緒庫引入:cpp11內建的執行緒其實是封裝了pthread執行緒,使用更加簡單,但是沒有pthread底層和控制能力強。 3).TLS變數,對全域性靜態常量資料和執行緒生命期繫結,關鍵字是thread_local。cpp11 errno變數是執行緒區域性的而不是全域性的。 3、程序退出:用quick_exit需要退出回撥的用at_quick_exit(目前LLVM還沒實現);異常退出還是要terminate實現。

VI 、"為改變思考方式而改變“ 總結: 1、nullptr引入,用單一職責思維,避免NULL存在指標和整型的二義性,nullptr_t型別可以進行賦值到指標和進行比較運算(與指標的)。 2、=default恢復編譯器預設的函式,方便書寫和保證POD型別;=delete指定刪除,方便禁止一些拷貝構造賦值和移動拷貝構造賦值函式,全域性和普通函式的某個過載版本也可以禁止。 3、lambda函式程式設計的引入,注意捕獲列表中傳值和傳引用區別(都是定義初始化仿函式閉包物件,但是&可獲得呼叫時上下文值,&自定義型別效能更高,但要小心使用)。在stl仿函式,泛型程式設計,複雜函式中作為匿名函式廣泛使用。lambda相比仿函式還是有區別的,只能函式內部初始化和使用,自定義仿函式和普通函式可以在不同作用域初始化和使用,所以使用時候區分就好。

VII、融入實際應用" 總結: 1、alignas是設定變數的對齊大小,alignof是獲取變數的對齊大小,可以單獨對變數對齊進行設定;stl庫裡面的align函式,aligned_storage和aligned_union模板對記憶體塊進行對齊調整。 2、通用屬性,cpp11引入的[[noreturn]](用在異常,終止,無限迴圈函式中)和[[carries_dependency]](用在弱記憶體模型並行程式設計中)屬性宣告符號。 3、Unicode字串,1)cpp11中預設的string 是utf8編碼,儲存省空間,增刪查詢也是可以的(utf16更加方便些),計算文字數需轉換到u16string。 2)c++11對於字元轉換用基於locale的codecvt,也可以直接用wstring_convert配合codecvt_utf8_utf16等直接進行轉換,注意utf16有大小端。 3)輸出時候的一些設定,內部會呼叫設定相關的函式,cpp98添加了wifstream和wofstream類,但是cpp11沒有u16ifstream和u32ofstream等,需要轉換到更節省的utf8型別。 4)原生字串字面量,語法R”()”,但是轉義字元不能再使用。

VIII、c++11和boost關係,boost的使用:

你可以大致看下C++11比C++03多了什麼。那些東西很多都是從boost庫里拉過去的。主要是智慧指標、執行緒、hash資料結構。
正則表示式,另外,boost裡面還有filesystem我認為比較實用。

儘量使用c++11,在使用boost可以獲得比較方便的方案時候,可以採用boost,如:filesystem,date_time(其實用cpp11實現也是可以的)。

下面是使用xcode下使用filesystem的例子:

標頭檔案的新增,借鑑預設的lib searchpath,如下:

$(inherited)

$(PROJECT_DIR)/boost_test

$(PROJECT_DIR)/boost_test/boost

測試程式碼:

程式碼見:整合專案見github。


拓展閱讀:

http://blog.jobbole.com/44015/

http://zh.cppreference.com/w/cpp

http://www.cplusplus.com/reference/