为什么placement-new 调用标准的placement operator new 函数?

时间:2021-06-15 23:45:39

标签: c++ placement-new

采用单个参数的 placement-new 表达式将在该内存中构造一个 T 类型的对象。

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

 int x = 10;
 int* p = new(&x) int{1024};
  • 你能解释一下编译器在上面的步骤中在int的内存地址中构造一个新的x吗?

  • 为什么 placement-new 表达式不直接在它作为指针获取的内存地址处构造一个对象,而不是调用一个什么都不做只返回其指针参数的操作符函数?

1 个答案:

答案 0 :(得分:1)

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

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

没有必要在语言中设置一条特殊规则,说明 operator new 不被展示位置 new 表达式调用。相反,编译器可以通过直接将 int 对象构建到 &x 中而不先调用 operator new 来简单地优化代码,因为它已经知道位置 operator new 将只返回其第二个论点。

(实际上,实际情况比这要复杂一些。如果T是数组类型,则调用operator new[]而不是operator new,编译器可能会从{ {1}} 比数组实际占用更多的内存,并在构造数组之前调整返回的指针。还有与过度对齐类型相关的特殊规则,实际上还有一些特殊情况用于放置 new 和删除。这些详细信息与此答案无关。)