在C ++初始化列表的默认值(Default values in C++ initializer l

2019-07-18 02:30发布

我昨天才刚刚得知指定参数初始化列表中的项目是可选的。 然而,什么是在这种情况下会发生什么规则?

在下面的例子中,将PTR被初始化为0,切换到错误的,酒吧缺省构造? 我想这个问题是有点多余,因为会有小点初始化列表,如果未指定的参数值==未定义行为。

难道我还需要指出的C ++标准,指出在不被给定的参数初始化列表项的情况下的行为的部分?

class Bar
{
    Bar() { }
};

class SomeClass;
class AnotherClass
{
public:
    SomeClass *ptr;
    bool toggle;
    Bar bar;

    AnotherClass() : ptr(), toggle(), bar() { }
    // as opposed to...
    // AnotherClass() : ptr(NULL), toggle(false), bar(Bar()) { }
};

Answer 1:

是,构件将分别被一个默认构造的对象初始化为零和。

在C ++ 11标准规定在12.6.2 / 7此行为:

在MEM-初始化表达式列表或支撑-INIT-列表被用于初始化指定子对象(或者,在一个委派构造,完整的类对象的情况下)按照8.5用于直接初始化的初始化规则。

反过来,8.5 / 10读取:

)一个对象,其初始化为空集括号的,即,(,应值初始化。

段落8.5 / 7限定值初始化

到的类型T是指值初始化的对象:

  • 如果T是一个(可能是CV-合格)类型(第9节)与用户提供的构造(12.1),然后对T中的默认构造函数被调用(并形成不良的初始化如果T没有可访问的缺省的构造) ;
  • 如果T是一个(可能CV修饰)非工会类没有用户提供的构造类型,则该对象是零初始化,并且如果T的隐式声明的缺省的构造是不平凡的,该构造函数被调用。
  • 如果T是一个数组类型,则每个元素是值初始化;
  • 否则,该对象被初始化为零。

最后,8.5 / 5定义零初始化

到零初始化对象或类型T表示的参考:

  • 如果T是一个标量类型(3.9),该对象被设置为值0(零),作为一个整体常量表达式,转换至T;
  • 如果T是一个(可能CV修饰)非工会类型,每个非静态数据成员,并且每个基础类子对象是零初始化和填充被初始化为零比特;
  • 如果T是一个(可能是CV-合格)联合类型,对象的第一非静态命名的数据成员是零初始化并且填充被初始化为零比特;
  • 如果T是一个数组类型,每一个元素是零初始化;
  • 如果T是引用类型,则不执行初始化。


Answer 2:

在下面的例子中,将PTR被初始化为0,切换到错误的,酒吧缺省构造?

是。 如果成员初始化器上出现的与空括号的初始化器列表中,则该成员初始化值 。 这意味着,数值类型会被初始化为零,指针为null,类使用该构造函数默认构造。

如果不包括在名单初始化剂的成员的话,那么这反而被默认初始化 ; 在这种情况下。 数值和指针类型会留下未初始化。

难道我还需要指出的C ++标准,指出在不被给定的参数初始化列表项的情况下的行为的部分?

C ++ 11 12.6.2 / 7指定的规则是相同的直接初始化。

C ++ 11 8.5 / 16指定如果初始化剂是()对象是值初始化。

C ++ 11 8.5 / 7限定值的初始化。



Answer 3:

Initialisations覆盖在[dcl.init](又名8.5)

点10说:

)一个对象,其初始化为空集括号的,即,(,应值初始化。

价值初始化时,简单地说,缺省建筑类和零初始化非类类型。



文章来源: Default values in C++ initializer lists