0

値の初期化の規則による。値の初期化が発生します。

1,5) 名前のない一時オブジェクトが空の括弧または中括弧のペアで構成される初期化子で作成された場合 (C++11以上);

2,6) 動的記憶域期間を持つオブジェクトが、括弧または中括弧の空のペアで構成される初期化子を持つ new 式によって作成される場合 (C++11以上)。

3,7) 非静的データ メンバーまたは基底クラスが空の括弧または中括弧のペアを持つメンバー初期化子を使用して初期化される場合 (C++11以上)。

4) 名前付き変数 (自動、静的、またはスレッドローカル) が、中かっこのペアで構成される初期化子で宣言されている場合。

些細な例

struct A{
    int i;
    string s;
    A(){};
};

A a{} 
cout << a.i << endl // default initialized value

コンストラクターを明示的に宣言せずに、デフォルトのデフォルト ctor のままにしておきます // コンパイラーが生成したものを取得します。

struct A{
    int i;
    string s;

};
A a{};
cout << a.i << endl // zero-initialized value

ただし、別の構造体を使用しています。

struct A{
    int i;
    string s;

};

struct B{
    A a;
    int c;
};

B a{};
cout << a.a.i << endl // default initialized , even tho we did not , int struct B , declared A a{}.

ai の値は、ルールに反する {} / () 構造を使用しなくても、ゼロで初期化されます (私が間違っていない場合)。

構造体 B で同じロジックを使用する:

struct A{
    int i;
    string s;

};

struct B{
    A a;
    int c;
};

B b;
cout << b.c << endl; // default inicialized

私たちはルールに従って行動します。

最後の例:

struct A
{
    int i;
    A() { } 
};

struct B { A a; }; 

std::cout << B().a.i << endl;

B().ai も、明示的にコンストラクターを宣言し、削除されていない間、ゼロで初期化されます。

これらの値がゼロで初期化されるのはなぜですか? ここに記載されている規則により、ゼロ初期化ではなくデフォルト初期化する必要があります。

回答ありがとうございます。

4

2 に答える 2

2

A集合体かそうでないかの違いです。

[dcl.init.aggr] (強調鉱山)

集合体は、ユーザー提供のコンストラクター(12.1) を持たない配列またはクラス (条項 9) 、非静的データ メンバーのブレースまたはイコール初期化子 (9.2)、プライベートまたは保護された非静的データ メンバー (条項11)、

したがって、A宣言されたコンストラクターがない場合、集計の初期化A a{}の効果があると言います

空の初期化リストを使用して各メンバーを構築します。

集約内のメンバーよりもリスト内の初期化句の数が少ない場合、明示的に初期化されていない各メンバーは、空の初期化子リストから初期化されます。

したがって、整数メンバーをゼロに値初期化するint{}andを取得します。std::string{}

既定のコンストラクターを指定すると、集計プロパティが失われ、intメンバーが初期化されないままになるため、アクセスは未定義の動作と見なされます。


具体的には:

a.iユーザー定義のコンストラクターを提供したため、このコードはアクセス時の未定義の動作です。そのため、int iフィールドは構築後も初期化されていません。

struct A{
    int i;
    string s;
    A(){};
};

A a{} ;
cout << a.i << endl;

b.cでリストの初期化を実行しなかったため、このコードはアクセス時に未定義の動作を示しB bます。

struct B{
    A a;
    int c;
};

B b;
cout << b.c << endl;

他のすべてのコードは問題なく、整数フィールドをゼロで初期化します。ブレースを使用しているシナリオでは、集計初期化{}を実行しています。

最後の例は、 value-initializationを実行しているため、少し注意が必要です。Bは集合体であるため、ゼロで初期化されます([dcl.init])。

各基本クラスのサブオブジェクトはゼロで初期化されます

Aしたがって、サブオブジェクトの整数メンバーにアクセスしても問題ありません。

于 2017-11-03T13:44:15.550 に答える