【问题标题】:operator new for array of class without default constructor没有默认构造函数的类数组的新运算符
【发布时间】:2010-03-26 02:35:18
【问题描述】:

对于没有默认构造函数的类,可以使用 operator new 和placement new 来声明该类的数组。

当我阅读More Effective 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;
}

【问题讨论】:

  • 这有点像stackoverflow.com/questions/2498183/…,但这个问题实际上并没有产生任何答案,只是“全局运算符 new 是一个不应该出现的愚蠢特性”的许多变体首先是 C++,任何称它为裤子气味的人”。另一方面,这个确实有一些答案,基本上“没有区别,只需使用正确版本的operator delete”:stackoverflow.com/questions/2499895/…
  • 如果您记得delete[] 您的记忆,您会看到它的唯一不同之处。 :)

标签: c++ placement-new new-operator


【解决方案1】:

我很惊讶 Effective C++ 会建议你使用像 void* 这样的东西。

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2013-03-16
          • 2022-01-01
          • 2014-03-03
          • 2023-03-20
          • 2014-01-22
          • 1970-01-01
          • 2015-07-07
          • 2012-09-01
          • 1970-01-01
          相关资源
          最近更新 更多