2017-10-30 12 views
0

私はC++ 11規格案(N3242改訂)を読み、次の文に出くわした: 参照メンバー

(12.7建設と破壊)。重大ではないコンストラクタを持つオブジェクトの場合、コンストラクタが実行を開始する前にオブジェクト の非静的メンバまたは基本クラスを参照すると、結果が不定になります。

私はFooの次のデフォルトコンストラクタを理解するように未定義の動作をしている(それがユーザー定義されているので、コードi(&a.i)? の作品にFooのコンストラクタは、(簡単ではありません)、私は、コンストラクタの実行前にメンバーaを参照しています。

struct A 
{ 
    int i; 
}; 

struct Foo 
{ 
    A a; 
    int* i; 
    Foo() : a(), i(&a.i) 
    {} 
}; 

UPD:多分タイプint*のメンバーの使用量はそれほど有益ではない(タイプintは、例えば、より適している)

+2

_ "メンバーのコンストラクタを実行する前に参照しています。" _いいえ、そうではありません。あなたは 'a()'で構築しました。 'a.i'は初期化されていませんが、アドレスを取ってもOKです。 –

+0

メンバー 'i'は 'int'型ですか?それは大丈夫ですか?私はそのようなC + +の文の意味を理解することはできません11 – LmTinyToon

+0

@underscore_d、あなたは間違ったrefferingの例を挙げてくださいできますか?それは本当に私を混乱させる – LmTinyToon

答えて

2

私が理解しているように、Fooのデフォルトのコンストラクタは未定義の動作をしています(コードi(&a.i)

いいえ。あなたが引用する表現は、「コンストラクタが実行を開始する前に」というフレーズを使用しています。我々はMEM-初期化子iを初期化する場合でも、我々は(ai前に宣言されているので)a後には、既に構築されていることをやっているので、これは完全に罰金です。 Aには些細なコンストラクタがないため、2人のメンバーが切り替えられたとしても、プログラムは正常です。

このセクションの例を見ると、その文言の意図が明確になっています。特にsecond example

struct W { int j; }; 
struct X : public virtual W { }; 
struct Y { 
    int* p; 
    X x; 
    Y() : p(&x.j) { // undefined, x is not yet constructed 
    } 
}; 

Xは(理由virtualベースの)非自明なコンストラクタを持っているので、それが構築されています前に、私たちはxを参照してください、しかしpの初期化は、まさにそれを行います。したがって、UB。

+0

私が理解しているように、標準的なステートメントは 'Foo'ではなく' a'のメンバーのコンストラクタを参照していますか? – LmTinyToon

+0

@LmTinyToon質問は分かりません。この文は実際にはまったく当てはまりません。 'Foo'オブジェクトが構築される前に' Foo'のメンバにアクセスする可能性がある場合に適用されます。 'Foo'内には、非自明のコンストラクタを持つメンバーはいないので、この節の目的のために間違って行うことはできません。 – Barry