什么是新展示位置?

What is a placement new?

我对展示位置有一些疑问 new:

int x;
int* p = new(&x) int{10};
std::cout << x; // 10

我很困惑!有时我会找到“新运营商”其他时候我会找到“新运营商”?!

有时我发现 operator new 函数的重载称为 placement 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;

What is a placement new?

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

When we say placement new, do we refer to new expression

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

“放置语法”也用于指代此。

or operator new (function)?

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

标准放置运算符 new 什么都不做,returns 指针参数不变。


示例:

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

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

下面不是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);

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

P.S。从 C++11 开始,可以使用 std::allocator_traits<std::allocator>::construct 来代替 placement new,而从 C++20 开始就有了 std::construct_at。与 placement new 不同,这些替代项是 constexpr (C++20 起)。


Is this a placement new even the first parameter is not a pointer?

是的,无论放置参数的类型如何,new(5u)int 仍然是放置新表达式。

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

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

P.S。显示的 operator new 实际上已损坏,因为它 returns null.