C ++:const引用和初始化顺序

时间:2011-10-12 21:30:16

标签: c++ const-reference

我想知道我是否正在使用下面的好方法:

  • 我想构建一个父类(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++ ?
}

2 个答案:

答案 0 :(得分:6)

不,这已经破了。您的mB将引用您传递给A对象的构造函数的任何内容,而不是mFoo。相反,你应该说:

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

请注意,mB是构造函数参数的副本,而不是引用,因此您的MyTest函数没问题。

答案 1 :(得分:3)

由于您希望B对象保留对父成员的引用,因此您必须使用mB而非mFoo初始化foo

你是正确的,成员变量的顺序很重要,因为它决定了初始化的顺序。令人惊讶的是构造函数中的初始值设定项的顺序确定它们被调用的顺序!请参阅Constructor initialization-list evaluation order