POD与非POD类类型的默认初始化

4
C++标准规定(8.5/5):
默认初始化类型为 T 的对象意味着:
  • 如果T是非POD类类型(条款9),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化无效)。
  • 如果T是数组类型,则每个元素都会默认初始化。
  • 否则,该对象将被零初始化。
使用该代码:
struct Int { int i; };

int main()
{
    Int a;
}

对象a是默认初始化的,但显然a.i不一定等于0。这是否与标准相矛盾,因为Int是POD且不是数组?

编辑:将class更改为struct,以使Int成为POD。


“显然,a.i不一定等于0”,为什么?“否则,该对象将被初始化为零。” - Viruzzo
您正在阅读过时的规范。在最新的规范中,默认初始化将使您的值未初始化。 - Johannes Schaub - litb
@JohannesSchaub-litb,你能展示一下更新后的文本吗? - Belloc
3个回答

6
根据2003标准第8.5.9节的规定:
如果未为对象指定初始化程序,并且对象是非POD类类型(或其数组),则应默认初始化对象; 如果对象是const限定类型,则基础类类型必须具有用户声明的默认构造函数。否则,如果未为非静态对象指定初始化程序,则该对象及其子对象(如果有)具有不确定的初始值); 如果对象或其任何子对象是const限定类型,则程序无效。
您展示的类是POD,因此应用了突出显示的部分,因此您的对象将根本不会初始化(因此您引用的8.5/5节根本不适用于这种情况)。
根据最新标准的最终工作草案第8.5 / 5节的引用如下:
对于类型T的默认初始化对象意味着: - 如果T是(可能是cv-qualified)类类型(第9条),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化无效); - 如果T是数组类型,则每个元素都被默认初始化; - 否则,不执行任何初始化。

1
根据标准,POD的所有非静态数据成员必须具有相同的访问控制;它不需要是“public”。 - Gorpik
@Björn 我手头没有标准。我在问题中复制的部分是从 SO 中其他问题中获取的。你的答案如何与我上面展示的标准部分相关联? - Belloc
@Björn 根据 http://stackoverflow.com/q/1613383/1042389 ,我的例子是默认初始化。还可能是什么? - Belloc
@user1042389:那个回答中引用的部分定义了如果使用这三种方法之一初始化对象会发生什么。我引用的部分定义了在你的示例中没有任何一种方法适用。你的示例根本没有进行初始化。 - Björn Pollex
@user1042389:Thomas Maierhofer在他的回答中给出了这样一个例子。 - Björn Pollex
显示剩余7条评论

1
你的变量没有初始化。 使用


Int a = Int();

要初始化您的POD或声明一个标准构造函数使其成为非POD; 但出于性能原因,您也可以使用未初始化的POD:

Int a;
a.i = 5;

0
不,对象a没有默认初始化。如果你想要进行默认初始化,你需要这样写:
Int a = Int() ;

没错,它是默认初始化的。Int a; 要求用默认构造函数构造 aInt a = Int(); 要求使用默认构造函数构造一个临时的 Int 对象,然后使用这个临时对象复制构造 a,尽管编译器可以(并且很可能会)跳过复制构造函数,直接使用默认构造函数直接构造 a - Gorpik
@TonyK @Thomas 无论如何,Int a = Int(); 怎么能被视为默认初始化? Int() 值初始化一个临时变量为0,然后再复制到a中。 - Belloc

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