Question

I am wondering if I am using the good approach in the following :

  • I want to construct a parent class (class A), this class should own an instance of a given "Foo" class
  • I want the parent class to own a child class member (class B) and this member should have a reference to the foo member of the parent class.

The code below seems to works, however I am wondering whether I was just "lucky" that the compiler was sympathetic enough.

For clarity, I added comment and my question in the comments below.

Thanks !

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++ ?
}
Était-ce utile?

La solution

No, this is broken. Your mB will hold a reference to whatever you passed to the constructor of the A object, not to mFoo. Instead, you should say:

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

Note that mB is a copy of the constructor argument, and not a reference, so your MyTest function is fine.

Autres conseils

Since you want your B object to hold a reference to the parent's member, you must initialize mB with mFoo not foo.

You are correct that the order of the member variables is important, since it determines the order of the initialization. It might come as a surprise that the order of the initializers in the constructor does not determine the order they are called! See Constructor initialization-list evaluation order.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top