C ++ 11メンバー初期化子リストとクラス内初期化子?

アーメド・T・アリ

C ++ 11でオブジェクトメンバー変数を初期化するこれらの方法の違いは何ですか?別の方法はありますか?どちらが良いですか(パフォーマンス)?:

class any {
  public:
    obj s = obj("value");
    any(){}
};

または

class any {
  public:
    obj s;
    any(): s("value"){}
};

ありがとう。

Piotr Skotnicki

いいえ、これらは同じではありません

それらの違いは、直接初期化コピー初期化に適用されるものと同じです。これは微妙ですが、非常に混乱することがよくあります。

§12.6.2[class.base.init]:

  1. mem-initializerexpression-listまたはbraced-init-listは、直接初期化の8.5の初期化規則に従って、指定されたサブオブジェクト(または、委任コンストラクターの場合は完全なクラスオブジェクト)を初期化するために使用されます。[...]

  2. 非委任コンストラクターで、特定の非静的データメンバーまたは基本クラスがmem-initializer-idで指定されていない場合(コンストラクターにctor-initializerがないためにmem-initializer-listがない場合を含む)エンティティが抽象クラス(10.4)の仮想基本クラスではない場合、

    —エンティティが中括弧または等しい初期化子を持つ非静的データメンバーである場合、エンティティは8.5で指定されているように初期化されます

§8.5[dcl.init]:

  1. フォームで発生する初期化

    T x = a;

引数の受け渡し、関数の戻り、例外のスロー(15.1)、例外の処理(15.3)、および集計メンバーの初期化(8.5.1)は、コピー初期化と呼ばれます

member-initializer-listで非静的データメンバーを初期化することは、直接初期化のルールに従います。これは、移動/コピーする必要のある中間の一時データを作成しません(コピーの省略なしでコンパイルされた場合)。データメンバーはコピー可能/移動可能である必要があります(コピーが省略されている場合でも)。さらに、直接初期化は明示的なコンテキストを導入しますが、コピー初期化は非明示的です(初期化用に選択されたコンストラクターがのexplicit場合、プログラムはコンパイルされません)。

言い換えると、次のobj s = obj("value");ようobjに宣言されている場合構文はコンパイルされません

struct obj
{
    obj(std::string) {}
    obj(const obj&) = delete;
};

または:

struct obj
{
    obj(std::string) {}
    explicit obj(const obj&) {}
};

より具体的な例として、以下はコンパイルされませんが:

struct any
{
   std::atomic<int> a = std::atomic<int>(1); // ill-formed: non-copyable/non-movable
   std::atomic<int> b = 2; // ill-formed: explicit constructor selected
};

これは:

struct any
{
    std::atomic<int> a;
    std::atomic<int> b{ 2 };
    any() : a(1) {}
};

どちらが良いですか(パフォーマンス)?

コピーエリジオンが有効になって両方の同一の性能を有します。コピーエリジオンが無効になって、すべてのインスタンス作成時の追加コピー/移動のコンストラクタ呼び出しがあり、コピーの初期化(構文が使用されているobj s = obj("value");の一つである)が。


別の方法はありますか?

ブレース-OR-等しい初期化構文は、1つの実行を可能にするダイレクト・リストの初期化をも。

class any {
public:
    obj s{ "value" };
    any() {}
};

他に違いはありますか?

言及する価値のある他のいくつかの違いは次のとおりです。

  1. 中括弧または等しい初期化子は、クラス宣言とともにヘッダーファイルに存在する必要があります。
  2. 両方を組み合わせると、member-initializer-listbrace-or-equal-initializerよりも優先されます(つまり、brace-or-equal-initializerは無視されます)。
  3. (C ++ 11のみ、C ++ 14まで)中括弧または等しい初期化子を使用するクラスは、集計型の制約に違反します。
  4. ブレース・オア・イコール初期化子構文それが実行することはできません直接、初期化以外のダイレクト・リストの初期化を

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

C ++ 11の統一された初期化:初期化子リストと複数パラメーターコンストラクターの間のあいまいさ?

分類Dev

c ++:初期化子リスト順のコンストラクター

分類Dev

非静的メンバー初期化子を持つクラスのC ++ 11集約初期化

分類Dev

C ++コンストラクタ初期化子リストのテンプレート配列の初期化

分類Dev

C ++初期化子リスト機能:メンバーを初期化せずに関数を呼び出しますか?

分類Dev

配列としてのc ++ 11初期化子リスト

分類Dev

C ++:代入なしのコンストラクタ初期化子リストの代替?

分類Dev

C ++は、他のパラメーターを持つコンストラクターの初期化子リストを取得します

分類Dev

C ++の初期化子リストとクラスの初期化。引数なしのコンストラクターがありますが、初期化リストを使用する必要がありますか?

分類Dev

C ++の初期化子リストとクラスの初期化。引数なしのコンストラクターがありますが、初期化リストを使用する必要がありますか?

分類Dev

C ++入門書には、「= default」コンストラクターに初期化子リストを使用できると書かれています

分類Dev

C ++初期化子リストのオーバーロードの曖昧性解消

分類Dev

C ++初期化子リストとデフォルト値

分類Dev

C ++ 11以降では、初期化子リストのベクトルを初期化する方法はありますか?

分類Dev

初期化子はあるが条件がないC ++ 17ifステートメント

分類Dev

複雑な割り当てを持つc ++コンストラクタ初期化子リスト

分類Dev

'using std :: foo'ディレクティブをコンストラクター初期化子リストにローカルに適用します(C ++)

分類Dev

C ++の初期化子リストから指定されたサイズでプライベートメンバー配列を作成しようとしています(<vector>の使用は禁止されています)

分類Dev

C ++ 11クラス内初期化子が括弧を使用できないのはなぜですか?

分類Dev

エラーC3074:配列は初期化子リストでのみ初期化できます

分類Dev

コンストラクター内のすべてのメンバーを初期化しないクラスをC ++ 11で初期化する方法

分類Dev

p。のメンバー初期化子リストの例がありません。C ++を使用したプログラミングの原則と実践の184、第2版

分類Dev

クラス内メンバー初期化子と初期化リスト間の競合解決

分類Dev

このリスト初期化子の動作は、Visual Studio C#コンパイラのバグとして報告する必要がありますか?

分類Dev

C ++で、初期化子リストで基本クラスのテンプレート引数を繰り返す必要があるのはなぜですか?

分類Dev

中括弧で囲まれた初期化子リストを含むC ++ 11 g ++

分類Dev

C ++コンストラクタ初期化子リストで非組み込み型の配列を初期化するにはどうすればよいですか?

分類Dev

C ++:ネストされた構造体のフラット初期化子リスト?

分類Dev

C ++ 11VS2013クラスPODメンバーの初期化

Related 関連記事

  1. 1

    C ++ 11の統一された初期化:初期化子リストと複数パラメーターコンストラクターの間のあいまいさ?

  2. 2

    c ++:初期化子リスト順のコンストラクター

  3. 3

    非静的メンバー初期化子を持つクラスのC ++ 11集約初期化

  4. 4

    C ++コンストラクタ初期化子リストのテンプレート配列の初期化

  5. 5

    C ++初期化子リスト機能:メンバーを初期化せずに関数を呼び出しますか?

  6. 6

    配列としてのc ++ 11初期化子リスト

  7. 7

    C ++:代入なしのコンストラクタ初期化子リストの代替?

  8. 8

    C ++は、他のパラメーターを持つコンストラクターの初期化子リストを取得します

  9. 9

    C ++の初期化子リストとクラスの初期化。引数なしのコンストラクターがありますが、初期化リストを使用する必要がありますか?

  10. 10

    C ++の初期化子リストとクラスの初期化。引数なしのコンストラクターがありますが、初期化リストを使用する必要がありますか?

  11. 11

    C ++入門書には、「= default」コンストラクターに初期化子リストを使用できると書かれています

  12. 12

    C ++初期化子リストのオーバーロードの曖昧性解消

  13. 13

    C ++初期化子リストとデフォルト値

  14. 14

    C ++ 11以降では、初期化子リストのベクトルを初期化する方法はありますか?

  15. 15

    初期化子はあるが条件がないC ++ 17ifステートメント

  16. 16

    複雑な割り当てを持つc ++コンストラクタ初期化子リスト

  17. 17

    'using std :: foo'ディレクティブをコンストラクター初期化子リストにローカルに適用します(C ++)

  18. 18

    C ++の初期化子リストから指定されたサイズでプライベートメンバー配列を作成しようとしています(<vector>の使用は禁止されています)

  19. 19

    C ++ 11クラス内初期化子が括弧を使用できないのはなぜですか?

  20. 20

    エラーC3074:配列は初期化子リストでのみ初期化できます

  21. 21

    コンストラクター内のすべてのメンバーを初期化しないクラスをC ++ 11で初期化する方法

  22. 22

    p。のメンバー初期化子リストの例がありません。C ++を使用したプログラミングの原則と実践の184、第2版

  23. 23

    クラス内メンバー初期化子と初期化リスト間の競合解決

  24. 24

    このリスト初期化子の動作は、Visual Studio C#コンパイラのバグとして報告する必要がありますか?

  25. 25

    C ++で、初期化子リストで基本クラスのテンプレート引数を繰り返す必要があるのはなぜですか?

  26. 26

    中括弧で囲まれた初期化子リストを含むC ++ 11 g ++

  27. 27

    C ++コンストラクタ初期化子リストで非組み込み型の配列を初期化するにはどうすればよいですか?

  28. 28

    C ++:ネストされた構造体のフラット初期化子リスト?

  29. 29

    C ++ 11VS2013クラスPODメンバーの初期化

ホットタグ

アーカイブ