2

对于没有默认构造函数的类,可以使用 operator new 和placement 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;
}
4

4 回答 4

2

这不是必需的。operator new 和 operator new[] 之间的唯一区别是第一个使用关键字 new 调用,另一个使用关键字 new[] 调用。两者都分配原始内存。

只要确保当您最终释放内存(您的代码只是泄漏)时,您调用的 delete 或 delete[] 匹配 new 或 new[]。

于 2010-03-26T02:41:08.847 回答
2

我很惊讶 Effective C++ 会建议你使用像void*.

new[]做了一件非常具体的事情:它分配一个动态大小的数组。分配有它的数组应传递给delete[]. delete[]然后读取一个隐藏的数字以查找数组中有多少元素,并像您对p[i].~A();.

但是,这种用法与此不兼容。new[]该数组是静态大小的,如果不正确使用(no ),就无法获得隐藏的数字或动态大小的破坏operator,而这又需要默认构造函数。C++ 的真正弱点。

如果您按照其他人的建议delete[]在最后调用main,您的代码可能会崩溃。相反,您需要使用operator delete[],这看起来像是一个错字,只是等待发生的事故。

如果必须使用此技巧,请使用非数组operator new和充足的注释。operator delete但我不会认为这是特别有效的 C++。

于 2010-03-26T07:31:15.780 回答
1

在这种情况下,它不是严格需要的。它们都将分配相同数量的内存,但一个会需要delete,一个会delete[]在最后需要。使用new[]使您的意图更加清晰,这就是为什么在这里使用它。

于 2010-03-26T02:44:48.700 回答
0

它并不是真正需要的——它只是让您有机会为数组分配内存,而不是为单个对象的内存分配内存,如果您选择这样做的话。

于 2010-03-26T02:47:52.740 回答