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
将 default-initialize 该数组。由于数组的元素是标量,我希望这意味着值都被设置为0。
在C ++ 11中,似乎不再保证会发生这种情况。但也许正如Mooing Duck在评论中指出的那样,也许这不再是默认初始化的情况,而是一些保留预期行为的其他形式。引文欢迎。
答案 0 :(得分:22)
最终效果几乎相同。在C ++ 03中, default-initialize 的使用仅限于非POD类类型,因此最后一点从未应用过。在C ++ 11中,该标准通过消除关于使用默认初始化的条件来简化措辞,并更改默认初始化的定义以覆盖所有情况,以便对应之前发生的事情。
答案 1 :(得分:3)
根据cppreference.com(因为它使用比标准更友好的语言):
默认初始化在以下三种情况下执行:
3)当a中没有提到基类或非静态数据成员时 构造函数初始化列表和该构造函数被调用。
值初始化在以下三种情况下执行:
3,7)初始化非静态数据成员或基类时 使用带有一对空括号
的成员初始值设定项or braces (since C++11)
请注意,C ++ 11部分属于or braces
,而不属于整个段落。
和
对T类型的对象进行值初始化意味着:
- 如果T是数组类型,则每个元素都是值初始化的;
- 否则,对象是零初始化
所以在C ++ 11中,默认初始化不会对成员进行零初始化,但值初始化会这样做。
答案 2 :(得分:2)
严格地说, default-initialize 的定义已从C ++ 03更改为C ++ 11。但是还要考虑到对象是_default-initialize_d的情况发生了变化:
§8.5p9C++ 03陈述:
如果没有为对象指定初始化程序,并且该对象是(可能是cv限定的)非POD类类型(或其数组),则该对象应默认初始化;如果对象是const限定类型,则底层类类型应具有用户声明的默认构造函数。否则,如果没有为非静态对象指定初始化程序,则该对象及其子对象(如果有)具有不确定的初始值;如果对象或其任何子对象是const限定类型,则程序格式不正确。
§8.5p11C++ 11陈述:
如果没有为对象指定初始化程序,则默认初始化该对象;如果未执行初始化,则具有自动或动态存储持续时间的对象具有不确定的值。
正如@JamesKanze已经指出的那样,当没有指定非POD类类型的对象的初始化器时,在C ++ 03中执行 default-initialization 。在C ++ 11中,如果没有指定初始化程序,则对象(任意类型)是默认初始化。由于此更改,还必须更改 default-initialize 的定义,以便与C ++ 03兼容。
您的示例与默认初始化无关。始终如此,其初始值设定项为空括号的对象是值初始化。