构造函数初始化列表中的循环依赖项
问题描述:
以下定义明确吗?构造函数初始化列表中的循环依赖项
class A;
class B;
// define A, which takes B& in constructor
// define B, which takes A& in constructor
class C
{
A a;
B b;
public:
C() : a(b), b(a) { /* stuff with a and b */ }
}
完整的示例在ideone.com。
只要A
和B
的构造函数对引用没有做任何操作,它是安全/定义好的吗?
答
N4140 [class.cdtor]/1读取:
对于具有一个非平凡构造方法的对象,参考任何非静态成员或基类的构造函数前的对象 的开始执行结果在未定义的行为。对于具有非平凡的析构函数的对象,在析构函数完成后引用该对象的任何非静态成员或基类 执行会导致未定义的行为。
虽然这段经文本身并不意味着行为是否定义良好,但下面的例子说明了这一点。下面是摘录:
struct B : public A { int j; Y y; }; // non-trivial
extern B bobj;
B* pb = &bobj; // OK
因此,答案是:是的,你的情况的行为,如果你没有在A
构造指的是b
成员或基类是明确界定。
为什么downvote?让我知道我该如何改进这个问题。 – Claudiu
我不认为编译器允许你执行'a(b)',因为当'a'被初始化时,'b'还没有被初始化。 – user3528438
@ user3528438:确实如此,ideone示例编译并运行。但是,这是因为我很幸运,还是因为它在标准中有明确的定义? – Claudiu