placement new 是 C++ 中的一个特性,用于在已分配的内存上构造对象,而不是在自由存储区(heap)上分配内存并构造对象。它的语法形式如下:
new (pointer) Type (arguments);
其中,pointer
是已分配内存的地址,Type
是要构造的对象类型,arguments
是传递给对象构造函数的参数。
通过 placement new,可以在特定的内存位置上创建对象,这在某些情况下非常有用,比如在共享内存、内存池等场景中。由于 placement new 可以显式地指定对象的构造位置,因此它提供了更多的灵活性和控制权。
需要注意的是,使用 placement new 构造的对象,在使用完毕后需要手动调用其析构函数来释放资源,并通过调用 delete
或者 delete[]
来释放其占用的内存。
例子:
-
void *shmaddr = mmap(NULL, size_, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
mmap
函数用于将一个文件或者其他对象映射到内存中。NULL
表示内核选择映射的地址,size_
表示映射的大小,PROT_READ | PROT_WRITE
表示允许读写访问,MAP_SHARED
表示映射的内存区域可被多个进程共享,fd
是打开的文件描述符,0
表示从文件的起始位置开始映射。
-
new(shmaddr) ShmSlice(init);
- 在映射的共享内存地址上使用placement new语法构造一个
ShmSlice
对象,init
是构造函数的参数。
- 在映射的共享内存地址上使用placement new语法构造一个
-
auto deleter = [](ShmSlice *ptr) { ptr->~ShmSlice(); }
- 创建一个lambda表达式作为deleter,用于在
std::shared_ptr
销毁时调用ShmSlice
对象的析构函数。
- 创建一个lambda表达式作为deleter,用于在
-
slice_ = std::shared_ptr<ShmSlice>(reinterpret_cast<ShmSlice *>(shmaddr), deleter);
- 创建一个
std::shared_ptr
对象slice_
,将其与映射的共享内存地址关联,并指定了上述自定义的deleter函数。reinterpret_cast
用于将void*
指针转换为ShmSlice*
指针。
- 创建一个
这样,通过std::shared_ptr
的管理,确保了在共享内存不再被引用时,对象会被正确地销毁,从而释放共享内存。