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

16

我昨天才知道指定初始化列表项的参数是可选的。但是,在这种情况下会发生什么规则呢?

在以下示例中,ptr是否将被初始化为0,toggle为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()) { }
};

可能是构造函数初始化列表为空初始化的重复问题。 - Justin
3个回答

14
是的,成员将分别初始化为零和默认构造对象。
C++11标准在12.6.2/7中指定了此行为:
“mem-initializer中的表达式列表或大括号初始化列表用于根据8.5的直接初始化初始化规则初始化指定的子对象(或在委托构造函数的情况下初始化完整类对象)。”
反过来,8.5/10中写道:
“其初始化程序为空括号集合即()的对象应进行值初始化。”
第8.5/7段定义了“value-initialized”:
“对于类型T的对象进行值初始化的意思是:”
- 如果T是一个(可能是cv-qualified的)类类型(第9条),并且具有用户提供的构造函数(12.1),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化无效); - 如果T是一个(可能是cv-qualified的)非联合类类型而没有用户提供的构造函数,则对象被零初始化,并且如果T的隐式声明默认构造函数是非平凡的,则会调用该构造函数; - 如果T是一个数组类型,则每个元素都进行值初始化; - 否则,对象将被零初始化。
最后,8.5/5定义了“zero-initialized”:
“对于类型T的对象或引用进行零初始化的意思是:”
- 如果T是标量类型(3.9),则将对象设置为值0(零),作为整数常量表达式取值为0,并转换为T; - 如果T是(可能是cv-qualified的)非联合类类型,则每个非静态数据成员和每个基类子对象都被零初始化,并将填充初始化为零位; - 如果T是一个(可能是cv-qualified的)联合类型,则该对象的第一个非静态命名数据成员被零初始化,并且填充被初始化为零位; - 如果T是一个数组类型,则每个元素都进行零初始化; - 如果T是一个引用类型,则不执行初始化。

6
在下面的例子中,会将ptr初始化为0,toggle为false,并且Bar默认构造吗?
是的。如果成员初始化器出现在初始化器列表中,括号为空,则该成员将进行值初始化。这意味着数值类型将被初始化为零,指针将被初始化为null,并使用具有默认构造函数的类来构造该构造函数。
如果根本不在初始化器列表中包含该成员,则它将被默认初始化;在这种情况下,数字和指针类型将保持未初始化状态。
我还可以指向C ++标准的哪个部分,说明在没有给出参数的初始化程序列表项的情况下的行为吗?
C ++11 12.6.2 / 7指定规则与直接初始化相同。
C ++11 8.5/16指定如果初始值设定项为(),则对象将进行值初始化。
C ++11 8.5 / 7定义了值初始化。

2

初始化在[dcl.init](也称8.5)中有涵盖。

第10点说:

其初始化程序为空括号集,即()的对象应进行值初始化。

值初始化简而言之,对于类,默认构造函数;对于非类类型,零初始化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接