提问人:akanesora 提问时间:7/6/2023 最后编辑:Jan Schultkeakanesora 更新时间:7/6/2023 访问量:122
安置新的基本实现是什么?
What is the underlying implementation of placement new?
问:
T *p = ::operator new(sizeof(T));
new (p) T;
我想知道该语法是如何工作的,因为放置 new 被声明为:
void* operator new(std::size_t, void*)
第二个参数似乎指向对象的存储,那么 C++ 如何连接到 ?void*
new (p) T
void*
在 gcc libsupc++ 中,实现很简单:
// Default placement versions of operator new.
_GLIBCXX_NODISCARD inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
{ return __p; }
_GLIBCXX_NODISCARD inline void* operator new[](std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
{ return __p; }
编译器是否负责将语法转换为放置的调用?new(*T) T
operator new
答:
5赞
ComicSansMS
7/6/2023
#1
编译器是否负责将语法 new(*T) T 转换为 放置操作员的召唤 新?
是的,没错。
放置不能作为库函数实现,无论如何都需要编译器进行特殊处理。您在 libsupc++ 源代码中看到的实际实现在这里可能会产生误导,因为该实现不会反映放置新调用的大多数关键属性。new
评论
0赞
Mooing Duck
7/6/2023
placement new 不需要编译器进行任何特殊处理。它的工作方式与任何其他新表达式完全相同。人们只是感到困惑,因为我们几乎从不将参数传递给new
0赞
ComicSansMS
7/6/2023
@MooingDuck我的意思是,一般情况下,它不能作为库函数实现。我并不是要暗示放置是这里各种变体中的特例。operator new
new
new
0赞
Mooing Duck
7/6/2023
迂腐地讲,在一般:P中几乎总是作为库函数实现。但是你是对的,表达式不能,因为它也调用了构造函数。operator new
new
1赞
Mooing Duck
7/6/2023
#2
使用正则表达式可以做两件事:它调用分配内存的函数(但不构造),然后在该位置调用构造函数,以在该内存处创建对象。new
operator new
对于放置 new,是空操作,只返回传入的指针,然后编译器调用该位置的构造函数,以在该内存中创建对象。operator new(std::size_t, void*)
//normal version calls these two functions
MyClass* pMemory = new MyClass; void* pMemory = operator new(sizeof(MyClass));
MyClass::MyClass(pMemory); //pseudo-syntax
您还可以创建自己的自定义方法,这些方法也适用于相同的常规机制。new
void* operator new(std::size_t, const char* name) {
return get_memory_by_name(name);
}
const char* allocation_name = "complex_float";
std::complex<float>* c = new(allocation_name) std::complex<float>{};
下一个:在自身之上构造对象 [复制]
评论
T
T*
new T
operator new(size_t)
operator new(size_t, int)
new (123) T
(...)
new
operator new(size,...)