繁体   English   中英

C ++ 11中默认初始化的含义已更改?

[英]Meaning of default initialization changed in C++11?

C ++ 2003 8.5 / 5说:

默认初始化类型T的对象意味着:

—如果T是非POD类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化格式不正确);

—如果T是数组类型,则每个元素都将默认初始化;

—否则,将对象初始化为零

[重点已添加。]

C ++ 2011标准将最后一项更改为

—否则, 不执行初始化

对于某些程序来说,这似乎是一个重大突破。 这是故意的吗?

编辑

这是一些激发这个问题的代码:

class Foo {
  public:
    Foo() : m_values() {}

    int m_values[3];
};

在C ++ 11之前,我认为在默认构造函数中明确提及m_values默认初始化该数组。 并且由于数组的元素是标量的,所以我希望这意味着所有值都设置为0。

在C ++ 11中,似乎不再保证会发生这种情况。 但是也许,正如Mooing Duck在评论中指出的那样,也许这不再是默认初始化的情况,而是某种保留了预期行为的其他形式。 欢迎引用。

最终效果几乎相同。 在C ++ 03中, 默认初始化的使用仅限于非POD类类型,因此最后一点从未应用。 在C ++ 11中,该标准通过消除有关使用默认初始化的条件来简化措辞,并更改了默认初始化的定义以涵盖所有情况,以对应以前发生的情况。

根据cppreference.com (因为它使用的语言比标准语言更友好):

默认初始化在以下三种情况下执行:

3)当构造函数初始化列表中未提及基类或非静态数据成员时,将调用该构造函数。

在以下三种情况下执行值初始化:

3,7)当使用带有一对空括号or braces (since C++11)的成员初始化器初始化非静态数据成员或基类时or braces (since C++11)

请注意,C ++ 11部分属于or braces ,而不属于整个段落。

和:

值初始化类型T的对象意味着:
—如果T是数组类型,则每个元素都进行值初始化;
—否则,该对象将被零初始化

因此,在C ++ 11中, 默认初始化不会对成员进行零初始化,而对值进行初始化

严格来说, default-initialize的定义已从C ++ 03更改为C ++ 11。 但是,还必须考虑到_default-initialize_d对象的情况已更改:

§8.5p9C ++ 03指出:

如果没有为一个对象指定初始化程序,并且该对象是(可能是cv限定的)非POD类类型(或其数组),则该对象应被默认初始化;否则,默认为初始化。 如果对象是const限定类型,则基础类类型应具有用户声明的默认构造函数。 否则,如果未为非静态对象指定初始化程序,则该对象及其子对象(如果有)具有不确定的初始值;否则,为false。 如果对象或其子对象为const限定类型,则程序格式错误。

§8.5p11C ++ 11指出:

如果未为对象指定初始化程序,则该对象为默认初始化;否则,默认为初始化。 如果未执行初始化,则具有自动或动态存储持续时间的对象的值不确定。

正如@JamesKanze指出的那样,当未为非POD类类型的对象指定初始化器时,将在C ++ 03中执行默认初始化 在C ++ 11中,如果未指定初始化程序,则将默认初始化对象(任意类型)。 由于此更改,还必须更改default-initialize的定义,以便与C ++ 03兼容。


您的示例与default-initialization没有关系。 通常情况下,将其初始化程序为一组空括号的对象进行值初始化

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM