操作员删除功能的放置形式

thb*_*thb 9 c++ placement-new

在他的新书TC++ PL4中, Stroustrup 对用户控制的内存分配和放置 - 或者更具体地说,关于神秘的"放置"的惯常做法 略有不同.在书的教派.11.2.4,Stroustrup写道:newdelete

delete除了可能通知垃圾收集器已删除的指针不再安全地派生之外,"placement "运算符不执行任何操作.

这意味着声音编程实践将通过调用放置delete来显式调用析构函数.

很公平.但是,没有更好的语法来调用放置而delete不是模糊

::operator delete(p);
Run Code Online (Sandbox Code Playgroud)

我问的原因是Stroustrup的教派.11.2.4没有提到这种奇怪的语法.事实上,Stroustrup没有详述此事; 他根本没有提到任何语法.我隐约不喜欢这样的外观::operator,它将命名空间解析的问题插入到与名称空间无关的内容中.不存在更优雅的语法吗?

作为参考,这里是Stroustrup在更全面的上下文中的引用:

默认情况下,operator new在免费商店中创建其对象.如果我们想要在其他地方分配对象怎么办?...我们可以通过提供带有额外参数的allocator函数将对象放在任何地方,然后在使用时提供这样的额外参数new:

void* operator new(size_t, void* p) { return p; }

void buf = reinterpret_cast<void*>(0xF00F);
X* p2 = new(buf) X;
Run Code Online (Sandbox Code Playgroud)

由于这种用法,new(buf) X提供额外参数的语法operator new()称为放置语法. 请注意,每个都operator new()将大小作为其第一个参数,并且隐式提供分配的对象的大小.在operator new()由所使用的new操作者是由通常的说法,匹配规则选择; 每个operator new()都有一个size_t作为它的第一个参数.

"放置" operator new()是最简单的这种分配器.它在标准标题中定义<new>:

void* operator new (size_t, void* p) noexcept;
void* operator new[](size_t, void* p) noexcept;

void* operator delete (void* p, void*) noexcept; // if (p) make *p invalid
void* operator delete[](void* p, void*) noexcept;
Run Code Online (Sandbox Code Playgroud)

delete除了可能通知垃圾收集器已删除的指针不再安全地派生之外,"placement "运算符不执行任何操作.

Stroustrup然后继续讨论new与竞技场的使用.他似乎没有delete再次提到安置.

Jer*_*fin 2

如果您不想使用::,则实际上不必使用。事实上,您通常不应该(不想)。

您可以提供::operator new和的替代品::operator delete(以及数组变体,尽管您永远不应该使用它们)。

但是,您也可以对类进行重载operator new和(是的,您可以执行数组变体,但仍然不应该使用它们)。operator delete

使用类似的东西void *x = ::operator new(some_size);会强制分配直接进入全局,operator new而不是使用特定于类的分配(如果存在)。当然,通常情况下,您希望使用特定于类的类(如果存在)(如果不存在则使用全局类)。这正是您从使用中得到的结果void *x = operator new(some_size);(即,没有范围解析运算符)。

与往常一样,您需要确保您的news 和deletes 匹配,因此您应该仅在/如果您曾经分配内存::operator delete时使用删除内存。::operator new大多数时候,您不应该使用::其中任何一个。

主要的例外是当/如果您实际上正在为某个类编写operator newand 。operator delete这些通常会调用::operator new以获得一大块内存,然后将其划分为对象大小的块。要分配这么大的内存块,它通常(总是?)必须显式指定::operator new,否则它最终会调用自己来分配它。显然,如果指定了::operator new分配数据的时候,也需要指定::operator delete来匹配。