c ++ placement new和overloading new

zah*_*pov 6 c++ memory-management operator-overloading

关于SO的许多问题都询问了C++的新特性(例1,例2)为什么要使用它.许多答案都说 - 自定义分配对象,如预先分配的空间.

但问题是 - 为什么需要为此安排新的?不仅仅是运营商的新超载足够吗?通过重载运算符new for class I可以精确控制从哪里获取内存 - 比如调用自定义分配器.那么为什么我需要为此目的安置新的?

Mar*_*ork 8

安置新

最好的例子是考虑std :: vector

std :: vector如何将新项放入数组中?

在向量的末尾添加新元素时,必须使用placement new.

class MyVector
{
    char*  data;
    size_t size;

    MyVector() : size(0), data(new char[1000]) {}

    // Placement new copy construction of element into array.
    void push_back(T const& t) { new (data + (sizeof(T) * size)) T(t); ++size;}
};
Run Code Online (Sandbox Code Playgroud)

请记住,您不能使用赋值或简单副本,因为该数组中尚不存在该元素(即内存空间还不是T(其值未定义))因此您必须新建一个新的T对象.阵列.

因此,将new放置为创建容器对象的方法.您可以分配比容器所需的空间更多的空间(而不是初始化它).然后使用placement new来初始化添加的元素.

超载新

重载new允许您控制对象具有的空间dynamic storage duration.也许您的预期使用模式不属于正常使用模式,您希望优化创建/销毁.也许你想要你想要建立自己的垃圾收集(对于特定类型).

主要的不同是:

  • 重载新控件为"动态存储持续时间"对象创建空间.
  • Placement new可以用于动态和自动存储持续时间对象(我想也是静态的).并在外部用于管理对象.

概述:

两者都是该语言的极端情况,很少在普通代码中使用(我想我已经编写了2个新的重载和一个使用贴片新的类(用于实际生产代码/不包括实验和测试)15年).

当您需要在现实生活中使用这些结构时,您将与经验丰富的团队合作数年,以验证您的设计.


ice*_*ime 6

你认为两者都可以用于解决同一类问题是正确的,但你缺少的是运算符新的重载是侵入性的(分配策略对象中),而新的放置不是(分配策略是完全的)独立).

Martin York的答案在这方面提供了一个很好的例子:std::vector<>保持自己的分配策略,而不对类型添加任何要求T.