C++初始化列表中的默认值

Jak*_*les 14 c++ standards initializer-list

我昨天才刚刚了解到,为初始化列表项指定参数是可选的.但是,在这种情况下会发生什么规则?

在下面的示例中,ptr是否会初始化为0,切换为false,而Bar默认构造?我想这个问题有点多余,因为如果未指定的参数值= =未定义的行为,初始化程序列表中几乎没有意义.

我是否也可以指向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()) { }
};
Run Code Online (Sandbox Code Playgroud)

Jon*_*Jon 13

是的,成员将分别初始化为零和默认构造的对象.

C++ 11标准在12.6.2/7中指定了这种行为:

mem-initializer中的expression-list或braced-init-list用于根据8.5的初始化规则初始化指定的子对象(或者,在委托构造函数的情况下,完成类对象)以进行直接初始化.

反过来,8.5/10读取:

初始值为空集括号的对象,即(),应进行值初始化.

第8.5/7段定义了价值初始化:

对值类型T的对象进行值初始化意味着:

  • 如果T是具有用户提供的构造函数(12.1)的(可能是cv限定的)类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的) ;
  • 如果T是一个(可能是cv限定的)非联合类类型而没有用户提供的构造函数,那么该对象是零初始化的,如果T的隐式声明的默认构造函数是非平凡的,则调用该构造函数.
  • 如果T是数组类型,那么每个元素都是值初始化的;
  • 否则,该对象被零初始化.

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

零初始化T类型的对象或引用意味着:

  • 如果T是标量类型(3.9),则将对象设置为值0(零),作为整数常量表达式,转换为T;
  • 如果T是(可能是cv限定的)非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的,并且填充初始化为零位;
  • 如果T是(可能是cv限定的)并集类型,则对象的第一个非静态命名数据成员将进行零初始化,并将填充初始化为零位;
  • 如果T是数组类型,则每个元素都是零初始化的;
  • 如果T是引用类型,则不执行初始化.


Mik*_*our 6

在下面的示例中,ptr是否会初始化为0,切换为false,而Bar默认构造?

是.如果成员初始化程序出现在具有空括号的初始化程序列表中,则该成员的值已初始化.这意味着数值类型将初始化为零,指向null,以及使用该构造函数的默认构造函数的类.

如果您根本没有在初始化列表中包含该成员,那么它将默认初始化 ; 在这种情况下.数字和指针类型将保持未初始化状态.

我是否也可以指向C++标准中指出初始化列表项未被赋予参数的情况下的行为?

C++ 11 12.6.2/7规定规则与直接初始化相同.

C++ 11 8.5/16指定如果初始化者是(),则对象是值初始化的.

C++ 11 8.5/7定义了值初始化.