2012-05-03 9 views
1

私のクラスの1つに対してコンストラクタが呼び出されたとき、私は奇妙なエラーに遭遇しています。基本的には、私がやっていることは次のとおりです:メンバー変数とコンストラクタコールに関するC++での作成プロセス

私は、クラス "B"、 "C"の2つのメンバー変数を持つクラス "A"を持っています。 "C" はタイプ "B"のメンバーで開始されるを持っています。だから、コンストラクタがなければならない:

A::A(): 
c(b) 
{} 

クラスは次のようにレイアウトされている場合、これが正常に動作します:

class A 
{ 
    C c; 
    B b; 
} 

マイ:クラスは次のようにレイアウトされている場合

class A 
{ 
    B b; 
    C c; 
} 

しかし、クラッシュしましたまず、コンストラクタで をc(b)に初期化しようとしている場合、cの前にbを作成する必要があります。私はこれが正しいかどうかわからない。 というコンストラクタがの前に割り当てられていますか?または、コンストラクタ内で参照されている メンバ変数が先に割り当てられ、コンストラクタの末尾に の参照されていないメンバ変数が割り当てられています(たとえば、 という別のメンバ変数 "C c2"がコンストラクタで参照されていない)

私は、Visual Studioの午前2010

答えて

1

ので、これが動作する方法は、ということである:あなたのオブジェクトの建設が始まる

  1. 非仮想基本クラスは、宣言の順に構築されます。
  2. 仮想基本クラスは、宣言の順に構築されます。
  3. 現在のクラス部分が作成されます(vtableなどの初期化)。
  4. メンバ変数は、初期化リストではなく、クラス宣言での外観順に構築されます。
  5. コンストラクタ本体が実行されます。
  6. オブジェクトの構築が完了しました。

私は#3の配置について間違いがありますが、私はほとんど仮想基盤を使用せず、このようなものに依存するコードを作成することはめったにありません。どうして?それは複雑で、そのようなコードは非常に壊れやすいからです。

破壊はまったく逆の順序で行われます。

+0

素晴らしいです、ありがとう! – coderunner

+0

番号4は7より前にいつでも実行できます。 –

1

あなたのメンバーは、彼らがあなたのクラス定義に現れる順序で初期化されます。 2番目の例では、cを初期化するときにbが初期化されていません。

私のコンパイラは、メンバーイニシャライザで順番を入れないと警告します。

+0

ありがとうございます。したがって、すべてのメンバ変数は、(たとえ明示的に初期化されていなくても)コンストラクタ呼び出しの先頭でクラス定義に現れる順番で参照されますか?たとえば、明示的に "b()"を入れていなくても、コンストラクタは基本的にはA :: A():b()、c(b){}です。 – coderunner

+0

@coderunner、私が理解しているところからかなりです。 – chris

+0

答えは正しいですが、おそらくオブジェクトの構築とオブジェクトの初期化を区別する必要があります。 –

1

メンバーは、常にクラス内の宣言の順序で作成されます。したがって

:それは完全に構築された後、あなたはBを渡しているよう

class A 
{ 
    B b; 
    C c; 
} 

が正常に動作します。
あなたがこれを行う場合は中:

class A 
{ 
    C c; 
    B b; 
} 

を次に、あなたが構築されていないBを使用してCを構築しています。値渡しの場合、おそらくコピーコンストラクタが破損します。参照渡しの場合は、Cコンストラクタ内で使用される場合は、初期化されていないオブジェクト 'B'を使用しています。

1

コンストラクタクラスの順序は、クラス定義内の順序によって異なります。クラスBコンストラクタがまだ呼び出されていないため、2番目の例は機能しません。ただ、明確化のため

0

は、あなたが言った:

私はタイプ "B"、 "C" の2つのメンバ変数を持つクラス "A" を、持っています。 "C"はタイプ "B"のメンバで開始されなければなりません。

をしかし、あなたのコードは::だからコンストラクタがなければならない

A::A() 
: c(b) 
{ 
} 

メンバ変数b、ないタイプBあなたの言葉遣いが言うようにcを初期化すると言います。

たぶん、あなたが欲しい:代わりに

A::A() 
: c(B()) 
{ 
} 

+0

"タイプBの" *メンバー*は同じものを意味しません( "タイプB"とは反対)?意味論的に何かが欠けていないことを確認したい。 – coderunner

+0

あなたの編集を見ただけです。いいえ、プログラムの設定方法メンバー変数としてbとcが必要です。 – coderunner

関連する問題