我想知道我是否正在使用下面的好方法:
下面的代码似乎有效,但我想知道我是否只是“幸运”,编译器足够同情。
为清楚起见,我在下面的评论中添加了评论和我的问题。
谢谢!
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++ ?
}
答案 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。