在执行非平凡的构造函数之前引用成员

时间:2017-10-30 12:37:52

标签: c++ c++11 constructor language-lawyer

我阅读了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更适合举例)

1 个答案:

答案 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。