了解类对象构造 [英] Understanding class object construction
问题描述
我在阅读N3797的第12.7条。下面的例子给出:
struct X {int i; };
struct Y:X {Y(); }; // non-trivial
struct A {int a; };
struct B:public A {int j; Y y; }; // non-trivial
extern B bobj;
B * pb =& bobj; // 1
int * p1 =& bobj.a; // 2 undefined,指基类成员
int * p2 =& bobj.y.i; // 3 undefined,指会员的会员
A * pa =& bobj;
B bobj;
extern X xobj;
int * p3 =& xobj.i;
X xobj;
此示例必须反映规则:
< >
对于具有非平凡构造函数的对象,在构造函数
开始执行之前,引用对象的任何
非静态成员或基类会导致未定义的行为。 / p>
但我有一个疑问。如果实现未对 // 1
, // 2
和 // 3
在静态方式,我们没有未定义的行为在 // 2
和 // 3
,因为(3.6.2 / 1):
执行常规初始化:
[...]
- 如果具有静态或线程存储持续时间的对象由构造函数
调用,如果初始化full-expression是
的对象的常量初始值;
[...]
这些零初始化和常量初始化称为
static初始化;所有其他初始化是动态
初始化。 必须在任何
动态初始化之前执行静态初始化。
有那个构造函数在非静态和基址之前调用。
div>
它也可以调用constexpr构造函数,Y :: Y()不是constexpr构造函数,所以B bobj下降到动态初始化。
I'm reading clause 12.7 of N3797. The following example is given:
struct X { int i; };
struct Y : X { Y(); }; // non-trivial
struct A { int a; };
struct B : public A { int j; Y y; }; // non-trivial
extern B bobj;
B* pb = &bobj; //1
int* p1 = &bobj.a; //2 undefined, refers to base class member
int* p2 = &bobj.y.i; //3 undefined, refers to member’s member
A* pa = &bobj;
B bobj;
extern X xobj;
int* p3 = &xobj.i;
X xobj;
This example must reflect the rule:
For an object with a non-trivial constructor, referring to any non-static member or base class of the object before the constructor begins execution results in undefined behavior.
But I've one doubt. If an implementation doesn't perform dynamic initialization for //1
, //2
, and //3
in a static way, we have no undefined behavior at //2
and //3
, because (3.6.2/1):
Constant initialization is performed:
[...]
— if an object with static or thread storage duration is initialized by a constructor call, and if the initialization full-expression is a constant initializer for the object;
[...]
Together, zero-initialization and constant initialization are called static initialization; all other initialization is dynamic initialization. Static initialization shall be performed before any dynamic initialization takes place.
That is, we have that constructor has called before a non-static and base. So the result of that example is implementation defined.
Is my reasoning correct?
"it may also invoke constexpr constructors", Y::Y() is not constexpr constructor so B bobj falls to dynamic initialization.
这篇关于了解类对象构造的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!