了解类对象构造 [英] Understanding class object construction

查看:138
本文介绍了了解类对象构造的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在阅读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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆