const引用和初始化顺序
C++ : const references and initialization order
我想知道我是否在下面使用了好的方法:
- 我想构造一个父类(类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++ ?
}
不,这是坏的。您的mB
将保存对传递给A
对象的构造函数的任何引用,而不是对mFoo
的引用。相反,你应该说:
A(const Foo & foo) : mFoo(foo), mB(mFoo) { }
请注意,mB
是构造函数参数的副本,而不是引用,因此您的MyTest
函数很好。
因为你想让B
对象保存对父对象成员的引用,你必须用mFoo
而不是foo
初始化mB
。
成员变量的顺序很重要,这一点是正确的,因为它决定了初始化的顺序。您可能会感到惊讶,构造函数中初始化式的顺序不是决定它们被调用的顺序!参见构造函数初始化-列表求值顺序
相关文章:
- lambda 作为接受其他参数的参数的初始化顺序
- 大括号或等于初始值设定项初始化顺序
- 类内初始化与构造函数初始化列表的顺序
- C++ 模板中的静态常量初始化顺序
- 如果在 C++ 构造函数中以错误的顺序初始化对象数据,会发生什么类型的错误
- 视觉C++:在 DLL 加载期间,全局变量初始化顺序是否具有确定性?
- 构造函数中没有参数的对象类成员按什么顺序初始化?
- 销毁 pthread 互斥体和 C++ 中的取消初始化顺序
- 线程局部变量的初始化顺序
- 初始化值是否保证通过其自己的地址反映,而不考虑内存顺序
- 类静态变量初始化顺序
- 具有静态存储持续时间的常量初始化变量的初始化顺序
- 解析 CRTP 初始化顺序
- 初始化相等C++的顺序
- 内联初始化的静态 const 类成员的初始化顺序保证
- 使用constexpr的全局初始化顺序
- 初始化与类类型相同的静态成员(静态初始化顺序问题)
- 结构化绑定的标识符是否按顺序初始化?
- c++中的求值顺序初始化数组
- c++标准和C语言在哪里说的是一样的:编译单元(.cpp文件)中的变量是按照声明的顺序初始化的