C++11/14新特性

13801 ワード

C++11はC++98から10年以上にわたって発表された新しい特性であり、多くのC++の機能と特性を拡張しているが、C++14はC++11に対するもう一つの補充と最適化であり、これらの新しい特性はC++を現代化された言語に近づけている.gccバージョンが5より大きい(clangバージョンが3.8より大きい)は、C++14を全面的にサポートしており、コンパイル時に-std=c++14オプションをオンにしてc++14の特性をサポートする必要があります.コードではc++11ではなくc++14の特性を直接使用することをお勧めします.
タイプの導出と判断
タイプ導出autoキーワードはすでにC++に存在し、変数タイプがregisterでなければautoである.しかし、registerの廃止(コンパイラ自動最適化変数格納位置)に伴い、autoの意味も多くなったため、c++11はキーワードautoに新しい意味を与えて自動タイプ導出を実現し、その導出段階はコンパイル期間で実現され、コンパイル期間間で左右の値が一致するかどうかを判断する必要があるため、コンパイルと実行速度に影響を与えることはない.
auto i = 1;         //OK
auto i;             //ERR,auto            

int max(int, int)
auto fun = max;     //OK

auto str = "ABC";   //OK

int max(auto a, auto b);    //ERR,       ,      

for (auto iter = vec.cbegin(); iter != vec.cend(); iter++){};  //OK

template <typename T1, typename T2, typename T3>
auto add(T2 a, T3 b) {          //  C++14   ,c++11   
    return a+b;
}

タイプ判定
タイプ判定の導入は主に変数のタイプを取得するためであり、decltype()を使用してコンパイル中に変数のタイプを取得することができる.
auto a = 1;
auto b = 2;
decltype(a+b) c;            //ok

シーケンス反復
C++11は、高速反復シーケンスのための簡単なfor構文を導入した.
std::vector<int> a = {1, 2, 3, 4};
for (auto item : a) {
    std::cout << item << std::endl;
}

リスト拡張の初期化
c++は{}を使用して配列、通常の構造体(構造関数と構造関数がない)の初期化を実現できることを知っていますが、初期化リストはオブジェクトと関数に使用できないため、c++11はstd::initializer_listを使用してこの特性を拡張しました.
#include 
class Test {
public:
    Test(std::initializer_list<int>){};
};

Test a = {1, 2, 3};     //    

int fun(std::initializer_list<int> list) {};

fun({1, 2, 3});         //      

次に、c++は統一的な形式を提供し、任意のタイプのオブジェクトの初期化を完了します.
class Person {
public:
    Person(std::string _name, int _age, std::string _id): name(_name), age(_age), id(_id){};
private:
    std::string name;
    int age;
    std::string id;
};

struct Person_{
Person_(std::string _name, int _age, std::string _id): name(_name), age(_age), id(_id){};
private:
    std::string name;
    int age;
    std::string id;
};
//        
Person c_person {"xiaoming", 18, "1234567"};    
Person_ s_person {"xiaohong", 17, "7654321"};

クラスプロパティの変更
クラス内のデフォルトの関数動作
指定されていない場合、c++はクラスにデフォルトのコンストラクタ、コピーコンストラクタ、付与関数、および構造関数を設定することを知っていますが、これらのデフォルト関数を必要としない場合があります.そのため、C++11にはこれらの特性を正確に制御する特性が導入されています.defaultはデフォルト関数の生成を指定し、deleteはデフォルト関数の無効化を指定します.デフォルトのコンストラクション関数とコンストラクション関数が無効な場合は、カスタム関数を指定する必要があります.
class Test {
public:
    Test() = default;       //   Test         ,     delete,          ,     
    ~Test() = default;      //      
    Test(const Test&) = delete;    //        
    Test& operator=(const Test&) = delete;  //       
};

Test a;
Test b(a);      //error,       
Test c = a;     //error,       

コンストラクタとくせい
C++11は2つの新しい構造関数特性を提供し、クラス構造の効率を高めるために使用され、それぞれ委託構造と継承構造であり、前者は主に多構造関数の場合に使用され、後者はクラス継承の面で使用される:-委託構造委託構造の本質は関数コードを簡略化し、他の構造関数コードを多重化する目的を達成するためである.
class Test {
public:
    Test() {
        a = 1;
    }
    Test(int _b) : Test() {
        b = _b;
    }

    int a,b;
};

Test t(2);    //   Test() a   1
  • 継承構造c++継承時には、構築関数のパラメータを積親クラスの構築関数に1つずつ渡す必要があり、この効率は低いため、c++11は継承構造の特性を導入し、usingキーワード:
  • class Test {
    public:
        Test(int _a, int _b) : a(_a), b(_b) {};
        int a,b;
    };
    
    class Test2 : public Test {
        using Test::Test;
    }
    
    Test2 t(2, 3);      //          

    明示的な制御虚関数の再ロード
    虚関数の特性のため、予期せぬ書き換えが行われる可能性があり、虚関数のリロードを正確に制御するために、c++11はoverridefinalキーワードを使用してこの特性の実現を完了し、以下の例を見る.
    class Test {
    public:
        Test() {};
        virtual int fun(int);
    };
    
    class Test2 : public Test {
        using Test::Test;
        int fun(int) override;      //            
        int fun(float) override;    //  ,         
    }

    一方、finalキーワードは、クラスの継承と虚関数の再ロードを明示的に終了するために使用されます.
    class Test {
    public:
        virtual int fun(int) final;
    };
    
    class Test2 final: public Test {
        int fun(int) override;     //  ,           finale,     
    };
    
    class Test3 : public Test2 {};  //  ,Test2     final,      
    nullptrおよびconstexprnullptrを導入したのはNULLの非難を解決するためであり、以前のc++ではNULLint0または0値のポインタとして定義することができ、これは問題をもたらす.
    void fun(int);
    void fun(void *);
    
    fun(NULL);  //               ,   NULL      

    一方、nullptrは空のポインタとして定義され、NULLによる問題を回避します.constexprは、ユーザーが明示的に宣言する関数またはオブジェクト構築関数を定義し、コンパイル中に定数になります.C++14から、constexptr関数は、ローカル変数、ループ、ブランチなどの簡単な文を内部で使用できます.
    //              
    constexpr int fun(const int n) {
        if (1 == n) return 1;
        else if (2 == n) return 1;
        else    return fun(n - 1) + fun(n - 2);
    }

    強列挙タイプ
    c++11はenum classを導入し、列挙が暗黙的に変換されないことを保証した.
    enum class test : int {
        v1 = 0,
        v2 = 1
    };
    
    if (test::v1 == 0)      //  ,   test   int     
    
    if (test::v1 == test(0))    //  ,         

    テンプレートの強化
    タイプ別名usingキーワードを使用して、別名をより直感的に定義します.
    typedef int (*fun)(int *);   //  c++   ,       `int *`,    int     ,   fun
    using fun = int (*)(int *);  //c++11,      
    
    template <typename T>
    using newType = std::pair;

    テンプレートと既定のテンプレートパラメータを長くする
    c++11は、テンプレートを定義するときにテンプレートにデフォルトのタイプを与えることができ、タイプを設定しないときにデフォルトのタイプを使用することができます.
    template <typename T = int, typename U = std::string>

    同時にc++11はテンプレートパラメータを任意の数に設定することができる:
    template <typename T1, typename... TS>      //            
    template <typename... TS>                   //  0 

    Lamda式
    Lamda式の構文は次のとおりです.
    [    ] (    )      ->      {
        //   
    }

    キャプチャリストはlamda式の内部で使用される外部パラメータのリストです.
    標準ライブラリ拡張
    c++11は、以下を含む複数の標準ライブラリを拡張した.新規追加コンテナ-配列コンテナ:std::array-単項チェーンテーブルコンテナ:std::forward_list-無秩序コンテナ:std::unordered_set-無秩序マッピング:std::unordered_map-メタグループ:std::tuple2.正規表現3.言語レベルのスレッドサポート4.スマートポインタと参照カウント5.関数バインドとパッケージ