【问题标题】:What is a placement new?什么是新展示位置?
【发布时间】:2021-08-29 22:37:47
【问题描述】:

我有一些关于安置new的问题:

int x;
int* p = new(&x) int{10};
std::cout << x; // 10
  • 当我们说放置new时,我们指的是new表达式还是运算符new(函数)?

     void* operator new(std::size_t, void*. int); // is this a placement new?
    

我很困惑!有时我会找到“新操作员”,有时我会找到“新操作员”?!

有时我会发现称为placement new 的运算符new 函数的重载:

   void* operator new(std::size_t, void*, int) // placement new?

这是另一个例子:

    void* operator new(std::size_t, std::size_t){
        std::cout << "operator new(std::size_t, std::size_t)\n";
        return nullptr;
    }

    int* p = new(5u)int;
  • 即使第一个参数不是指针,这也是新的展示位置吗?

【问题讨论】:

  • Placement-new 顾名思义:在指定位置“放置”一个“新”构造对象。如果您认为这令人困惑,那么在更复杂的场景中手动控制 destruction 很可能会触发 tick。
  • “Placement new”用于描述new 表达式和适当的operator new 重载。

标签: c++ placement-new


【解决方案1】:

什么是新展示位置?

它将一个动态对象构造到提供的存储区域中。

当我们说placement new时,我们指的是新的表达方式

是的,但专门针对未省略放置参数的新表达式。

“放置语法”也用来指代这个。

还是运算符new(函数)?

...也可以,虽然可能不那么频繁。这取决于上下文。在将对象初始化为运算符返回的地址之前,新表达式将调用其中一个新运算符。 Placement new 表达式调用一个placement operator new。

标准的放置操作符 new 什么都不做,并且返回指针参数不变。


例子:

以下是一个新表达式,其中省略了放置新参数。这会分配存储空间(将调用非放置运算符 new)并在该存储空间中创建一个对象。

T* p1 = new T();
//         ^ no placement parameter
delete p1; // don't forget to clean up

Following 不是 new 表达式,而是对非放置全局运算符 new 的调用。

void* storage = ::operator new(sizeof(T), alignof(T));

以下是带有放置参数的新表达式。这就是“安置新”。它创建一个对象而不分配存储空间。

T* p2 = new (storage) T(); // must include <new>
//          ^^^^^^^^^ placement parameter
p2->~T(); // don't forget to clean up
::operator delete(storage);

注意:放置 new 不一定要将对象构造到动态分配的内存中。

附:从 C++11 开始,std::allocator_traits&lt;std::allocator&gt;::construct 可以用来代替放置 new,并且从 C++20 开始有 std::construct_at。与placement new 不同,这些替代项是constexpr(C++20 起)。


即使第一个参数不是指针,这也是新的放置吗?

是的,new(5u)int 仍然是一个放置新表达式,与放置参数的类型无关。

除了void* 之外,没有标准的placement operator new 接受任何东西,但用户定义的placement operator new(例如问题中显示的)将允许使用这样的表达式。

这是该语言相当晦涩的特征。我从来没有见过这在实践中使用过。

附:显示的操作符 new 实际上被破坏了,因为它返回 null。

【讨论】:

  • 回复。最后一句话——placement-new 创建的对象被认为具有动态存储持续时间,即使它们不是在从免费存储获得的存储中创建的
  • @M.M 是的,这个词很难说。有动态对象的存储,还有被重用的存储,我指的是。
  • 请查看我的最后一个问题,我已对其进行了编辑。我差不多明白了。
  • @Maestro 好问题。我已经编辑了答案。
  • 非常感谢!真是令人惊叹和彻底的解释。在花了很多天努力理解它之后,你现在真的让我的模棱两可和困惑变得清晰了。是的,我同意我在上一个示例中以某种方式滥用了 operator new 的含义,但这只是为了澄清。再次感谢您!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-13
  • 2015-11-20
  • 1970-01-01
  • 2023-02-15
  • 1970-01-01
  • 2018-12-29
  • 1970-01-01
相关资源
最近更新 更多