在执行非平凡构造函数之前引用成员 我阅读C++ 11标准草案(N3242修订版),并在以下陈述中遇到:

在执行非平凡构造函数之前引用成员 我阅读C++ 11标准草案(N3242修订版),并在以下陈述中遇到:,c++,c++11,constructor,language-lawyer,C++,C++11,Constructor,Language Lawyer,(12.7施工和破坏)。对于具有非平凡构造函数的对象,引用该对象的任何非静态成员或基类 在构造函数开始执行之前,会导致未定义的行为 据我所知,以下Foo的默认构造函数具有未定义的行为(在一段代码I(&a.I)? Foo的构造函数并不简单(因为它是用户定义的),我指的是执行构造函数之前的成员a struct A { int i; }; struct Foo { A a; int* i; Foo() : a(), i(&a.i) {} }; UPD

(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
类型更合适)

据我所知,Foo的以下默认构造函数具有未定义的行为(在一段代码
I(&a.I)

不。您引用的措辞使用了短语“在构造函数开始执行之前”。但是,当我们在mem初始值设定项中初始化
i
时,我们是在
a
已经被构造之后进行初始化的(因为
a
是在
i
之前声明的),所以这是完全正确的

此外,即使两个成员被切换,程序仍然可以运行,因为
A
没有一个非平凡的构造函数

struct A
{
    int i;
};

struct Foo
{
    A a;
    int* i;
    Foo() : a(), i(&a.i)
    {}
};
如果您查看该部分中的示例,它们将阐明措辞的意图。尤其是:

X
有一个非平凡的构造函数(因为
virtual
base),所以我们在构建之前参考
X
,但是
p
的初始化就是这样做的。因此,UB

据我所知,Foo的以下默认构造函数具有未定义的行为(在一段代码
I(&a.I)

不。您引用的措辞使用了短语“在构造函数开始执行之前”。但是,当我们在mem初始值设定项中初始化
i
时,我们是在
a
已经被构造之后进行初始化的(因为
a
是在
i
之前声明的),所以这是完全正确的

此外,即使两个成员被切换,程序仍然可以运行,因为
A
没有一个非平凡的构造函数

struct A
{
    int i;
};

struct Foo
{
    A a;
    int* i;
    Foo() : a(), i(&a.i)
    {}
};
如果您查看该部分中的示例,它们将阐明措辞的意图。尤其是:


X
有一个非平凡的构造函数(因为
virtual
base),所以我们在构造之前引用
X
,但是
p
的初始化就是这样做的。因此,UB.

“我指的是在执行构造函数之前的成员a。”不,你不是。你只是用
a()
a.i
未初始化,但获取其地址是可以的。@下划线\d实际上,由于
a
在构造函数初始值设定项列表中,因此
a.i
的值被定义为零(整个结构
a
及其所有成员也被初始化为值)@LmTinyToon至于您的问题,在构造函数初始值设定项列表中,所有成员都存在于内存中。它们可能未初始化,但它们确实作为周围
Foo
对象的一部分存在(在本例中)@lmtinyton即使在这种情况下也没关系,因为初始化是按照类中声明成员变量的顺序进行的。这意味着
a
将被完全初始化,包括
a.i
,因此引用它并将其用作值是可以的。@lmtinyton在您的示例中没有任何内容与标准中的引用相矛盾的。再次,如果对象在自己的构造函数初始化列表中对自己的成员执行任何操作都是非法的,该语言不可能存在。“我指的是在执行构造函数之前的成员a。”不,你不是。你只是用
a()构造它
a.i
未初始化,但获取其地址是可以的。@下划线\d实际上,由于
a
在构造函数初始值设定项列表中,因此
a.i
的值被定义为零(整个结构
a
及其所有成员也被初始化为值)@LmTinyToon至于您的问题,在构造函数初始值设定项列表中,所有成员都存在于内存中。它们可能未初始化,但它们确实作为周围
Foo
对象的一部分存在(在本例中)@lmtinyton即使在这种情况下也没关系,因为初始化是按照类中声明成员变量的顺序进行的。这意味着
a
将被完全初始化,包括
a.i
,因此引用它并将其用作值是可以的。@lmtinyton在您的示例中没有任何内容与标准中的引用相矛盾的。再次,如果对象在自己的构造函数初始化列表中对自己的成员执行任何操作都是非法的,该语言不可能存在。据我所知,标准语句指的是成员
a
的构造函数,而不是
Foo
?@LmTinyToon我不理解这个问题。该语句在这里根本不适用-它将应用于如果在构建
Foo
对象之前,您可能要访问
Foo
的成员。在
Foo
中,我们没有任何具有非平凡构造函数的成员,因此就本条款而言,我们不会做错任何事情。据我所知,标准语句指的是成员的构造函数e> a不是
Foo
?@LmTinyToon我不理解这个问题。该语句在这里根本不适用-如果您在构建
Foo
对象之前潜在地访问
Foo
的一个成员,它将适用。在
Foo
中,我们没有任何具有非平凡构造函数的成员,因此存在就本条款而言,我们不会做错任何事。