繁体   English   中英

没有默认构造函数的类数组的新运算符

[英]operator new for array of class without default constructor

对于没有默认构造函数的类,可以使用运算符new和placement new声明此类的数组。

当我在“更有效的C ++”中阅读代码时,发现下面的代码(我修改了一部分).....

我的问题是,为什么在需要新运算符之后需要[]?

我在没有它的情况下对其进行了测试,但仍然可以使用。 有人可以解释吗?

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;
}

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

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

使我感到惊讶的是,Effective C ++会建议您使用像void*这样的hackish。

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

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

如果像其他人建议的那样在main的末尾调用delete[] ,则代码可能会崩溃。 取而代之的是,您需要使用operator delete[] ,它看起来像是一个错字,只是一个偶然的等待。

如果必须使用此技巧,请使用非数组operator newoperator delete以及大量注释。 但是我不会认为这种C ++特别有效。

在这种情况下,并不一定需要它。 它们都将分配相同数量的内存,但是其中一个将要求delete而一个将在末尾要求delete[] 使用new[]使您的意图更加清晰,这就是为什么在此使用它的原因。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM