C++11新特性
語言特性
-
移動語義
-
右值引用
-
轉發引用
-
可變模板
-
列表初始化
列表初始化,就是使用花括號進行初始化
std::vector<int> nums{1, 2, 3, 4, 5}; // 列表初始化 for (auto it : nums){ cout << it << endl; }
-
靜態斷言
編譯時斷言機制,允許在編譯時檢查某個條件是否為真。靜態編譯檢查編譯時的常量表示式。經常與型別特徵
type traits
一起使用。因為靜態斷言是在編譯時進行檢驗,所以可以用於不同編譯平臺進行執行前檢驗。static_assert(<constant-expressions>, <error-message>); static_assert(sizeof(int) >= 4, "Not support 32 bits integer"); template <typename T> void CheckInt(T* co, size_t size) { static_assert(std::is_integral<T>::value, "Not support 32 bits integer."); }
-
型別推導
auto
型別推導的使用,必須前面有可以隱式說明型別的語句。std::vector<int> nums; for (auto it : nums){ cout << it << endl; }
-
lambda表示式
-
decltype
型別宣告decltype運算子將會返回傳遞給它的表示式得到的型別。
int a = 0; decltype(a++) b;
-
型別別名
C++
中using
也可以宣告別名,相較於typedef
更易讀。template <typename T, typename T> using u_map = std::map<T, T>;
-
nullptr
空指標nullptr
空指標的使用可以規避掉以往設定為NULL
的風險。NULL
在編譯器中常常被設定為0
或者其它數字,此時判斷指標是否為NULL
,即判斷指標型別是否能夠等於整型值,並不安全。int* p = nullptr;
-
強型別列舉
強型別列舉不能隱式轉換為
int
型別,可以指定底層型別,如果未指定底層型別,會自動預設為int
型別。只能透過型別名訪問,是因為成員作用域侷限在型別中,並不公開。// 強型別列舉 enum class HttpState:uint32_t{ HTTP_OK, // private HTTP_BAD }; using State = HttpState; State state = State::HTTP_OK;
-
constexpr
宣告constexpr
會告訴編譯器在編譯時對其進行最佳化,所以會在編譯時即計算完。因此禁止呼叫執行時才完成的函式(如建構函式)。constexpr int Add(int a, int b) { return a + b; } int main(){ int a =3, b = 4; const int res = Add(a, b); std::cout << res << std::endl; }
-
委託構造
構造器能夠呼叫其它構造器進行初始化。
class MyClass{ MyClass(int a) :val(a){}; // default private MyClass() : MyClass(0){}; private: int val; }
-
使用者定義語義
-
顯式虛過載
override
告知編譯器,派生類會覆蓋基類中的虛擬函式,避免發生簽名不匹配和不存在相應虛擬函式。如果出錯會報錯。// explict virtual override class Base{ virtual void Add()=0; }; class Derived final: public Base{ void Add() override{ /* code */ }; };
-
Final
修飾符告訴編譯器,用於指示一個類不能被進一步繼承,或者一個虛擬函式不能被子類覆蓋。
// final修飾的虛擬函式無法覆蓋 class Cat{ public: virtual void showCatName() final{ // 限定不能被繼承 /* 顯示名字 */ } }; class MyCat : public Cat{ void showCatName(){ // 不能繼承父類,此時會編譯報錯 /* ... */ } } // final修飾的類無法繼承 class Base final{ virtual void Add() = 0; };
-
default
函式此修飾符用於告訴編譯器為
default
修飾的函式生成預設函式,noexcept
告訴編譯器不要丟擲異常,避免物件構建過程中丟擲異常,假如建構函式丟擲異常,其中有一些變數已經生成。那麼此時物件無法構建成功,已經生成的變數則無法析構,會導致丟失記憶體。class Myclass{ Myclass() noexcept = default; // 生成預設配置 };
-
deleted
函式此修飾符用於告訴編譯器不要為
delete
生成預設的函式,使其無法被例項化和呼叫。可以完成禁止複製、禁止移動等功能。class Myclass{ Myclass() noexcept = delete; // 禁止生成預設配置 };
-
範圍
for
迴圈std::vector<int> nums; for (auto it : nums){ cout << it << endl; }
-
移動語義特殊成員函式
-
顯式轉換功能
-
內聯名稱空間
-
非靜態資料成員初始化
C++11允許非靜態成員初始化。
class Cat{ Cat(int a) : val(a){} int val = 0; // 允許非靜態成員直接初始化 };
-
引用限定成員函式
-
尾部返回型別
允許使用
->
來為lambda
和函式指定返回型別。auto Func1() -> int{ /* code */ } auto Func2 = []() -> int{};;
-
noexcept
限定符:限定能否丟擲異常noexcept
關鍵字告訴編譯器該函式不會丟擲任何異常,從而允許編譯器最佳化。如果丟擲了異常,會用std::terminate
終止程式執行。可以省略一些編譯器生成一些異常處理程式碼。可以是條件性判斷丟擲異常。void Add(int a, int b) noexcept{ // 不會丟擲任何異常 } void AddIf(int a, int b) noexcept(false){ // 可能會丟擲異常 }
-
char32_t
char16_t
代表UTF-8
字串(1-4個位元組) -
原始字面字串
庫特性
-
std::move
-
std::forward
-
std::thread
thread
是引入的執行緒庫。 -
std::to_string()
to_string
能夠完成的作用是將數字轉換為字串。stoi()
函式將字元轉為數字,一定要注意提前檢查字元一定是數字,而不是數字意外的其它字元,否則會程式崩潰。 -
type_traits
型別特性庫型別特性庫包含了一組編譯時檢查型別特性的工具,可以配合
static_assert
使用。// 基本型別判斷包括整型、浮點型等 std::is_integral<T>::value // 檢查T是否是整數型別,value是一個靜態常量,其值為true或false // 型別修飾 std::remove_const<T> // 移除型別T的const修飾 // 型別轉換 std::add_const<T> // 為型別T新增const修飾 // 型別特性檢查 std::is_same<T, U> // 檢查兩個型別是否相同 // 條件型別 std::conditional<Condition, T, F> // Condition為true, 則型別為T,否則為F
-
智慧指標
智慧指標有三種,
share_ptr
共享指標,用於多個讀;weak_ptr
弱指標,解決共享指標迴圈引用計數無法下降問題;unique_ptr
獨佔指標,用於獨享資源。 -
std::chrono
chrono
是引入的一個定時器相關的庫,有system_clock
-
turples
-
std::tie
繫結 -
std::array
陣列容器,有強制型別檢查,連續儲存可以告訴訪問,可以用於儲存特定個數元素。
vector
是可以擴容的。std::array<int> intArray{1, 2, 3, 4, 5};
-
unordered containers
-
std::make_shared
-
std::ref
-
std::async
-
std::begin()
和std::end()
這兩個函式用於獲取物件的迭代器,
begin(string str)
等價於str.begin()
。