placement new 如何在指定内存上构造对象

// Default placement versions of operator new.
inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
{ return __p; }
inline void* operator new[](std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
{ return __p; }

如上,查看gcc中stl的源代码的实现方式。placement new 只是返回__p指针。若

class XX
{
    //define ctor,dctor here
    //data member
};
char buf[sizeof(XX)];
XX* ptr = new(buf) XX();

像上面这样使用placement new,请问XX是如何在那个指定的内存buf上完成构造的呢?明明只是把指针返回了啊。

阅读 5k
3 个回答

首先,你这里的调用的placement new不是头文件new中定义的那个placement new。你得写::operator new(...);才行。

然后关于这个placement new,C++标准中有如下声明(C++11):
18.6.1.3 Placement forms [new.delete.placement]
1 These functions are reserved, a C++ program may not define functions that displace the versions in the Standard C++ library (17.6.4). The provisions of (3.7.4) do not apply to these reserved placement forms of operator new and operator delete.

大意是说,这些函数是保留在那的,不能动,目前没什么用。

new运算符不负责调用构造器。如果你打算调用构造器,需要调用new表达式。

new表达式会先调用new运算符,然后在返回的指针上调用构造器。

前两种new运算符负责分配内存,但是最后一种由于不需要分配内存,但又要保持统一,所以把参数里的指针直接返回。

运算符:

// plain new
void *operator new(size_t);
// nothrow new
void *operator new(size_t, nothrow_t)
// placement new
void *operator new(size_t, void *)

表达式:

//plain new
Type *p = new Type(args);
// nothrow new
Type *p = new(std::nothrow) Type(args);
// placement new
new(p) Type(args);

考虑结构体如何初始化的问题。
只要分配好内存,你就可以把这段内存reinterpret_cast成你想要的类型,这个过程就让类的成员变量有了自己的内存空间,然后再调用这个类型的构造函数就可以了,原理就是这样。你自己也可以手动实现一个placement new

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题