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

Default values in C++ initializer lists

本文关键字:默认值 列表 初始化 c++      更新时间:2023-10-16

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

在下面的例子中,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()) { }
};

是,成员将分别初始化为0和默认构造对象。

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

使用mem初始化器中的表达式列表或带括号的初始化列表初始化指定的子对象(或,如果是委托构造函数(完整的类对象)8.5的直接初始化规则。

8.5/10依次为:

初始化式为一组空括号的对象,即();

8.5/7段定义了value-initialized:

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

  • 如果T是带有用户提供的构造函数的(可能是cv限定的)类类型(第9条)(12.1),则调用T的默认构造函数(和如果T没有可访问的默认值,则初始化是错误的构造函数),
  • 如果T是(可能是cv限定的)非联合类类型,则
  • 如果没有用户提供的构造函数,则对象是零初始化和if T隐式声明的默认构造函数
  • 如果T是数组类型,
  • 否则,对象为zero-initialized。
最后,8.5/5定义了zero-initialized:

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

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

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

是的。如果一个成员初始化器出现在初始化器列表中,并且带有空括号,则该成员是值初始化的。这意味着数值类型将被初始化为零,指针指向null,而具有默认构造函数的类将使用该构造函数。

如果你根本没有在初始化列表中包含成员,那么它将是默认初始化的;那样的话。数值和指针类型将保持不初始化。

还可以指出c++标准中说明初始化列表项未被给定参数时的行为的部分吗?

c++ 11 12.6.2/7指定了与直接初始化相同的规则。

c++ 11 8.5/16规定,如果初始化器是(),则对象是值初始化的。

c++ 11 8.5/7定义值初始化

初始化包含在[dcl]中。(也就是8.5)

第10点说:

如果对象的初始化式是一组空圆括号,即(),则应该进行值初始化。

值初始化是类的默认构造,非类类型的零初始化。