3

私は次のように良いアプローチを使用しているかどうか疑問に思っています:

  • 親クラス(クラスA)を作成したいのですが、このクラスは特定の「Foo」クラスのインスタンスを所有している必要があります
  • 親クラスに子クラスメンバー(クラスB)を所有させたいのですが、このメンバーには親クラスのfooメンバーへの参照が必要です。

以下のコードは機能しているように見えますが、コンパイラーが十分に同情的であったことを「幸運」だったのではないかと思います。

わかりやすくするために、以下のコメントにコメントと質問を追加しました。

ありがとう !

struct Foo
{
  std::string mValue;
};

class B
{
public:
  B(const Foo & foo) : mFoo_External(foo) {}
private:
  const Foo & mFoo_External; //this is an external reference to the member 
                             //(coming from A)
};

class A
{
public:
  //Here is the big question 
  //Shall I use : 
  //  A(const Foo & foo) : mFoo(foo), mB(mFoo) {}  
  //  or the declaration below
  A(const Foo & foo) : mFoo(foo), mB(foo) {}
private:
  //According to my understanding, the declaration 
  //order here *will* be important
  //(and I feel this is ugly)
  const Foo  mFoo;
  B mB;
};



void MyTest()
{
  std::auto_ptr<Foo> foo(new Foo());
  foo->mValue = "Hello";
  A a( *foo);
  foo.release();

  //At this point (after foo.release()), "a" is still OK 
  //(i.e A.mB.mFooExternal is not broken, although foo is now invalid)
  //
  //This is under Visual Studio 2005 : 
  //was I lucky ? Or is it correct C++ ?
}
4

2 に答える 2

6

いいえ、これは壊れています。は、ではなく、オブジェクトのコンストラクターmBに渡したものへの参照を保持します。代わりに、次のように言う必要があります。AmFoo

A(const Foo & foo) : mFoo(foo), mB(mFoo) { }

mBこれはコンストラクター引数のコピーMyTestであり、参照ではないため、関数は問題ないことに注意してください。

于 2011-10-12T21:38:02.410 に答える
3

オブジェクトに親のメンバーへの参照を保持させたいので、notでB初期化する必要があります。mBmFoofoo

初期化の順序を決定するので、メンバー変数の順序が重要であることは正しいです。コンストラクター内の初期化子の順序が、呼び出される順序を決定しないことに驚かれるかもしれません。コンストラクターの初期化リストの評価順序を参照してください。

于 2011-10-12T21:58:57.540 に答える