我阅读了c ++ 11草案标准(N3242修订版),并发表了以下声明:
(12.7建造和销毁)。对于具有非平凡构造函数的对象,引用该对象的任何非静态成员或基类 在构造函数开始执行之前导致未定义的行为。
据我所知,Foo
的默认构造函数有未定义的行为(在代码段i(&a.i)
中)?
Foo
的构造函数不是微不足道的(因为它是用户定义的),我在执行构造函数之前指的是成员a
。
struct A
{
int i;
};
struct Foo
{
A a;
int* i;
Foo() : a(), i(&a.i)
{}
};
UPD:使用类型int*
的成员可能不那么有用(类型int
更适合举例)
答案 0 :(得分:2)
据我所知,Foo的默认构造函数有未定义的行为(在代码段
i(&a.i)
中?
没有。您引用的措辞使用短语“在构造函数开始执行之前”。但是,当我们在 mem-initializer 中初始化i
时,我们在构建 a
之后才会执行(从{{1}开始在a
之前声明,所以这很好。
此外,即使这两个成员被切换,该程序仍然可以,因为i
没有非平凡的构造函数。
如果您查看该部分中的示例,他们会澄清措辞的意图。特别是second example:
A
struct W { int j; };
struct X : public virtual W { };
struct Y {
int* p;
X x;
Y() : p(&x.j) { // undefined, x is not yet constructed
}
};
有一个非平凡的构造函数(由于X
基础),所以我们在构造之前引用virtual
,但x
的初始化确实如此只是。因此,UB。