对于没有默认构造函数的类,可以使用运算符new和位置new来声明该类的数组。
当我在更有效的C++中阅读代码时,我发现代码如下(我修改了一些部分).....
我的问题是,为什么在运算符new之后需要[]?
我在没有它的情况下测试了它,它仍然可以工作。有人能解释吗?
class A {
public:
int i;
A(int i):i(i) {}
};
int main()
{
void *rawMemory = operator new[] (10 * sizeof(A)); // Why [] needed here?
A *p = static_cast<A*>(rawMemory);
for(int i = 0 ; i < 10 ; i++ ) {
new(&p[i])A(i);
}
for(int i = 0 ; i < 10 ; i++ ) {
cout<<p[i].i<<endl;
}
for(int i = 0 ; i < 10 ; i++ ) {
p[i].~A();
}
return 0;
}
发布于 2010-03-26 15:31:16
我很惊讶,Effective C++会建议你使用像void*
这样的黑客工具。
new[]
做了一件非常具体的事情:它分配一个动态大小的数组。使用它分配的数组应该传递给delete[]
。然后delete[]
读取一个隐藏的数字来找出数组中有多少个元素,并销毁对象,就像您对p[i].~A();
所做的那样。
然而,这种用法与之不兼容。该数组是静态大小的,如果不正确使用new[]
(无operator
),就无法获得隐藏的数字或动态大小的销毁,而这反过来又需要一个默认的构造函数。C++的一个真正的弱点。
如果你像其他人建议的那样,在delete[]
main
的末尾调用,你的代码可能会崩溃。相反,你需要使用operator delete[]
,这看起来像是一个拼写错误,只是一个等待发生的意外。
如果必须使用此技巧,请使用非数组operator new
和operator delete
以及大量注释。但我不认为这是特别有效的C++。
发布于 2010-03-26 10:41:09
这是不必要的。操作符new和操作符new[]之间唯一的区别是,第一个是通过使用关键字new调用的,而另一个是通过使用关键字new[]调用的。两者都分配原始内存。
只需确保当您最终释放内存时(这里的代码只是泄漏),您将调用与new或new[]匹配的delete[]或new[]。
发布于 2010-03-26 10:44:49
在这种情况下,它并不是严格需要的。它们都将分配相同的内存量,但一个需要delete
,另一个最终需要delete[]
。使用new[]
使您的意图更加清晰,这就是为什么在这里使用它。
https://stackoverflow.com/questions/2520843
复制相似问题