在尝试回答这个问题时,我发现代码int* p = new int[10]();
可以在VC9编译器中正常编译并将整数初始化为0。因此,我的问题如下:
- 首先,这是否是有效的C++代码还是微软的扩展?
- 它是否保证初始化数组的所有元素?
- 另外,如果我使用
new int;
或new int();
,是否有任何区别?后者是否保证初始化变量?
在尝试回答这个问题时,我发现代码int* p = new int[10]();
可以在VC9编译器中正常编译并将整数初始化为0。因此,我的问题如下:
new int;
或new int();
,是否有任何区别?后者是否保证初始化变量?首先,这是有效的C++代码还是微软扩展?
这是有效的C++代码,相关的标准部分是5.3.4,第一段包含了语法规则。
它能保证初始化数组的所有元素吗?
可以。第5.3.4/15段陈述:
创建类型为T的对象的new-expression会按如下方式初始化该对象:
...
- 如果new-initializer的形式为(),则该项进行值初始化(8.5)
其中,对于POD类型的值初始化意味着零初始化。
此外,如果我使用new int;和new int();有什么区别?后者是否保证初始化变量?
它们是不同的。根据上面的引用,new int()
将会零初始化整数。在同一段落的前一个块中:
如果省略了new-initializer:
如果T是(可能带有cv限定符的)非POD类类型(或其数组),则该对象进行默认初始化(8.5)。如果T是const限定类型,则基础类类型必须具有用户声明的默认构造函数。
否则,创建的对象具有未确定的值。如果T是const限定类型,或(可能带有cv限定符的)包含(直接或间接地)const限定类型成员的POD类类型(或其数组),则程序是非法的;
因此,new int
将不会初始化内存。
struct S { int x; };
void f () {
S s1; // s1.x is uninitialized here
S s2 = S(); // s2.x is zero here
}
我认为我们经常对内置类型的默认构造函数进行自己的解释;因为C++标准没有定义它(至少我找不到),我记得Stroustrup或Josuttis说它意味着T(),被描述为值初始化时是内置类型的"0转换为T类型"。
由于int*是一种内置类型,所以它被初始化为零。
但我真的不确定。
这是根据第5.3.4/1段有效的C++代码,由于特殊格式很难在此引用。
根据第5.3.4/15条款,如果使用form(),则该项将进行值初始化,请参见第8.5段,但简短的答案是是。
是的,在第一种情况下,变量未进行值初始化,可以是任何值,在第二种情况下,它进行了值初始化,并且将为零。
如果我可以猜测一下(如果我错了,我相信会被纠正):
后者()进行值初始化(在标准中称为值初始化),这使得整数在这种情况下具有值0。
这是标准的一个相当新的补充(C++03?),因此旧编译器可能不支持它,并且将其保留为未初始化状态。
我记得在从MSVS 2003切换到2005(我想是那个版本)时,我收到了很多关于这个的警告,其中编译器说“现在将对该成员进行零初始化,以前没有进行过”。
new int[]{1, 2}
是不起作用的。人们必须说new int[2]{1, 2}
,我认为这很糟糕。 - Johannes Schaub - litb