首页 > 解决方案 > 为什么placement-new 调用标准的placement operator new 函数?

问题描述

一个placement-new带有单个参数的表达式,该参数是一个指向预分配内存的指针,将T在该内存中构造一个类型的对象。

为什么它调用标准placement-new运算符void* operator new ( std::size_t count, void* ptr );,因为后者什么都不做,只返回它的指针参数?

 int x = 10;
 int* p = new(&x) int{1024};

标签: c++placement-new

解决方案


一般的规则是new (args...) T会调用operator new(sizeof(T), args...),并且这个函数需要返回void*。如果此operator new调用成功返回,则将对象构造到返回值指向的内存中。

这个通用规则足够强大,可以同时支持普通的 new 表达式new int和放置形式new (&x) int,而无需任何特殊情况。这两个表达式调用不同的重载operator new,这就是为什么前者分配而后者不分配的原因。无论如何,最后都会构造一个对象(除非operator new函数因抛出异常而失败)。

无需在语言中设置特殊规则,即表示operator new不被放置新表达式调用。相反,编译器可以通过直接构造int对象来简单地优化代码,&x而无需先调用operator new,因为它已经知道放置operator new只会返回其第二个参数。

(其实实际情况比这复杂一点。如果T是数组类型,则operator new[]调用 then 而不是operator new,编译器可能会请求operator new[]比数组实际占用更多的内存,并在构造之前调整返回的指针数组。还有一些与过度对齐类型有关的特殊规则,实际上还有一些用于放置 new 和 delete 的特殊情况。这些细节与这个答案无关。)


推荐阅读