C++11新特性

LemHou發表於2024-08-17

C++11新特性

語言特性

  1. 移動語義

  2. 右值引用

  3. 轉發引用

  4. 可變模板

  5. 列表初始化

    列表初始化,就是使用花括號進行初始化

    std::vector<int> nums{1, 2, 3, 4, 5}; // 列表初始化
    for (auto it : nums){
        cout << it << endl;
    }
    
  6. 靜態斷言

    編譯時斷言機制,允許在編譯時檢查某個條件是否為真。靜態編譯檢查編譯時的常量表示式。經常與型別特徵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.");
    }
    
  7. 型別推導

    auto型別推導的使用,必須前面有可以隱式說明型別的語句。

    std::vector<int> nums;
    for (auto it : nums){
        cout << it << endl;
    }
    
  8. lambda表示式

  9. decltype型別宣告

    decltype運算子將會返回傳遞給它的表示式得到的型別。

    int a = 0;
    decltype(a++) b;
    
  10. 型別別名
    C++using也可以宣告別名,相較於typedef更易讀。

    template <typename T, typename T>
    using u_map = std::map<T, T>;
    
  11. nullptr空指標

    nullptr空指標的使用可以規避掉以往設定為NULL的風險。NULL在編譯器中常常被設定為0或者其它數字,此時判斷指標是否為NULL,即判斷指標型別是否能夠等於整型值,並不安全。

    int* p = nullptr;
    
  12. 強型別列舉

    強型別列舉不能隱式轉換為int型別,可以指定底層型別,如果未指定底層型別,會自動預設為int型別。只能透過型別名訪問,是因為成員作用域侷限在型別中,並不公開。

    // 強型別列舉
    enum class HttpState:uint32_t{
        HTTP_OK, // private
        HTTP_BAD
    };
    using State = HttpState;
    State state = State::HTTP_OK;
    
  13. 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;
    }
    
  14. 委託構造

    構造器能夠呼叫其它構造器進行初始化。

    class MyClass{
        MyClass(int a) :val(a){}; // default private
        MyClass() : MyClass(0){};
    private:
        int val;  
    }
    
  15. 使用者定義語義

  16. 顯式虛過載
    override告知編譯器,派生類會覆蓋基類中的虛擬函式,避免發生簽名不匹配和不存在相應虛擬函式。如果出錯會報錯。

    // explict virtual override
    class Base{
        virtual void Add()=0;
    };
    class Derived final: public Base{
        void Add() override{
            /* code */
        };
    };  
    
  17. Final修飾符

    告訴編譯器,用於指示一個類不能被進一步繼承,或者一個虛擬函式不能被子類覆蓋。

    // final修飾的虛擬函式無法覆蓋
    class Cat{
    public:
        virtual void showCatName() final{ // 限定不能被繼承
            /* 顯示名字 */
        }
    };
    class MyCat : public Cat{
        void showCatName(){ // 不能繼承父類,此時會編譯報錯
            /* ... */
        }
    }
    // final修飾的類無法繼承
    class Base final{
        virtual void Add() = 0;
    };
    
  18. default函式

    此修飾符用於告訴編譯器為default修飾的函式生成預設函式, noexcept告訴編譯器不要丟擲異常,避免物件構建過程中丟擲異常,假如建構函式丟擲異常,其中有一些變數已經生成。那麼此時物件無法構建成功,已經生成的變數則無法析構,會導致丟失記憶體。

    class Myclass{
       Myclass() noexcept = default; // 生成預設配置
    };
    
  19. deleted函式

    此修飾符用於告訴編譯器不要為delete生成預設的函式,使其無法被例項化和呼叫。可以完成禁止複製、禁止移動等功能。

    class Myclass{
      Myclass() noexcept = delete; // 禁止生成預設配置
    };
    
  20. 範圍for迴圈

    std::vector<int> nums;
    for (auto it : nums){
        cout << it << endl;
    }
    
  21. 移動語義特殊成員函式

  22. 顯式轉換功能

  23. 內聯名稱空間

  24. 非靜態資料成員初始化

    C++11允許非靜態成員初始化。

    class Cat{
        Cat(int a) : val(a){}
        int val = 0; // 允許非靜態成員直接初始化
    };
    
  25. 引用限定成員函式

  26. 尾部返回型別

    允許使用->來為lambda和函式指定返回型別。

    auto Func1() -> int{
        /* code */
    }
    auto Func2 = []() -> int{};;
    
  27. noexcept限定符:限定能否丟擲異常

    noexcept關鍵字告訴編譯器該函式不會丟擲任何異常,從而允許編譯器最佳化。如果丟擲了異常,會用std::terminate終止程式執行。可以省略一些編譯器生成一些異常處理程式碼。可以是條件性判斷丟擲異常。

    void Add(int a, int b) noexcept{
        // 不會丟擲任何異常
    }
    void AddIf(int a, int b) noexcept(false){
        // 可能會丟擲異常
    }
    
  28. char32_t char16_t代表UTF-8字串(1-4個位元組)

  29. 原始字面字串

庫特性

  1. std::move

  2. std::forward

  3. std::thread

    thread是引入的執行緒庫。

  4. std::to_string()

    to_string能夠完成的作用是將數字轉換為字串。stoi()函式將字元轉為數字,一定要注意提前檢查字元一定是數字,而不是數字意外的其它字元,否則會程式崩潰。

  5. 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
    
  6. 智慧指標

    智慧指標有三種,share_ptr共享指標,用於多個讀;weak_ptr弱指標,解決共享指標迴圈引用計數無法下降問題; unique_ptr獨佔指標,用於獨享資源。

  7. std::chrono

    chrono是引入的一個定時器相關的庫,有system_clock

  8. turples

  9. std::tie繫結

  10. std::array

    陣列容器,有強制型別檢查,連續儲存可以告訴訪問,可以用於儲存特定個數元素。vector是可以擴容的。

    std::array<int> intArray{1, 2, 3, 4, 5};
    
  11. unordered containers

  12. std::make_shared

  13. std::ref

  14. std::async

  15. std::begin()std::end()

    這兩個函式用於獲取物件的迭代器,begin(string str) 等價於str.begin()

相關文章