在他的新书TC++PL4 中, Stroustrup对用户控制的内存分配和放置(或者更具体地说,关于神秘的“放置”)的常见做法 进行了略微不同的阐述。在书的教派。11.2.4,Stroustrup 写道:new
delete
“放置
delete
”操作符除了可能通知垃圾收集器删除的指针不再安全派生之外什么都不做。
这意味着良好的编程实践将遵循对放置的调用对delete
析构函数的显式调用。
很公平。但是,没有delete
比晦涩难懂的调用布局更好的语法了吗?
::operator delete(p);
我问的原因是Stroustrup的教派。11.2.4 没有提到这种奇怪的语法。事实上,Stroustrup 并没有详述这个问题。他根本没有提到语法。我隐约不喜欢 的外观::operator
,它将命名空间解析的问题插入到与命名空间无关的东西中。不存在更优雅的语法吗?
作为参考,以下是 Stroustrup 在更完整的上下文中的引用:
默认情况下,运营商
new
在免费商店中创建其对象。如果我们想要将对象分配到其他地方怎么办?...我们可以通过提供带有额外参数的分配器函数然后在使用时提供这样的额外参数来将对象放置在任何地方new
:void* operator new(size_t, void* p) { return p; } void buf = reinterpret_cast<void*>(0xF00F); X* p2 = new(buf) X;
由于这种用法,
new(buf) X
提供额外参数的语法operator new()
称为放置语法。 请注意,每个都operator new()
将大小作为其第一个参数,并且分配的对象的大小是隐式提供的。operator new()
运算符使用的由new
通常的参数匹配规则选择;每个operator new()
都有 asize_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;
“放置
delete
”操作符除了可能通知垃圾收集器删除的指针不再安全派生之外什么都不做。
Stroustrup 然后继续讨论在 arena 中放置位置的new
使用。他似乎没有再提到安置delete
。