初始化数组时使用(或不使用)括号
Posted
技术标签:
【中文标题】初始化数组时使用(或不使用)括号【英文标题】:Using (or not using) parentheses when initializing an array 【发布时间】:2015-07-02 13:47:18 【问题描述】:在我正在阅读的 c++ 代码中,有一些初始化为类似的数组
int *foo = new int[length];
还有一些喜欢
int *foo = new int[length]();
我的快速实验无法发现这两者之间有任何区别,但它们是并排使用的。
有区别吗,如果有呢?
编辑;因为有一个断言,第一个应该给出不确定的输出,所以这里是一个显示可疑数字 0 的测试;
[s1208067@hobgoblin testCode]$ cat arrayTest.cc
//Test how array initilization works
#include <iostream>
using namespace std;
int main()
int length = 30;
//Without parenthsis
int * bar = new int[length];
for(int i=0; i<length; i++) cout << bar[0] << " ";
cout << endl;
//With parenthsis
int * foo = new int[length]();
for(int i=0; i<length; i++) cout << foo[0] << " ";
cout << endl;
return 0;
[s1208067@hobgoblin testCode]$ g++ arrayTest.cc
[s1208067@hobgoblin testCode]$ ./a.out
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[s1208067@hobgoblin testCode]$
编辑 2;显然这个测试有缺陷,不要相信它 - 查看详细答案
【问题讨论】:
没有区别,只是调用了不带参数的构造函数 @celticminstrel,您正在打印一个值初始化的int
。相同的语法并不意味着它具有默认构造函数。 (作为参考,表达式 T(),其中 T 是非数组完整对象类型或(可能是 cv 限定的)void 类型的简单类型说明符或类型名称说明符,创建指定类型,其值是通过值初始化 (8.5) 类型 T 的对象产生的值;对于 void() 情况不进行初始化。)
见 Do the parentheses after the type name make a difference with new? 这是案例 A,在 C++11 中也是如此。
我从未真正见过数组初始化的括号。
@nilo,是的,您可以认为它们是具有构造函数的特殊非类类型。不幸的是,它并不总是如此一致。您会期望 int x;
使用“默认构造函数”并且 int x = int();
也使用默认构造函数,因为当您将 int
替换为合适的用户定义类型时会发生这种情况。然而,他们实际上做不同的事情。我想更好的类比是struct S int x;;
在执行S s;
和S s = S();
时的行为,尽管它与普通的int
案例一样直观。
【参考方案1】:
这一行default-initializeslength
int
s,也就是说你会得到一堆值不定的int
s:
int *foo = new int[length];
这条线value-initializes他们,所以你得到全零:
int *foo = new int[length]();
【讨论】:
在快速实验中,两者似乎都只有 0。这只是第一个版本的机会吗? @Jekowl,是的,在第一种情况下打印它们是未定义的行为。 不确定并不意味着“非 0”。它的意思是“可以是任何东西”。让它们碰巧为 0 是可以接受的,但不是你应该依赖的。 在标准下当然可以接受,但看起来它正在以两种方式进行零初始化...... @Jekowl 你接受你认为对你帮助最大的答案——你不必解释它。我不会把它当作个人的:)【参考方案2】:使用括号保证数组的所有元素都初始化为0。我只是尝试使用以下代码:
#include <iostream>
using namespace std;
int main(int,char*[])
int* foo = new int[8];
cout << foo << endl;
for(int i = 0; i < 8; i++)
foo[i] = i;
delete[] foo;
foo = new int[8];
cout << foo << endl;
for(int i = 0; i < 8; i++)
cout << foo[i] << '\t';
cout << endl;
delete[] foo;
foo = new int[8]();
cout << foo << endl;
for(int i = 0; i < 8; i++)
cout << foo[i] << '\t';
cout << endl;
delete[] foo;
return 0;
当我编译并运行它时,看起来foo
每次都分配在同一个内存位置(尽管你可能不能依赖它)。对我来说,上述程序的完整输出是:
0x101300900
0x101300900
0 1 2 3 4 5 6 7
0x101300900
0 0 0 0 0 0 0 0
因此,您可以看到foo
的第二次分配没有触及分配的内存,使其处于与第一次分配时相同的状态。
【讨论】:
以上是关于初始化数组时使用(或不使用)括号的主要内容,如果未能解决你的问题,请参考以下文章