【发布时间】:2013-06-30 15:58:07
【问题描述】:
在他的新书中TC++PL4, Stroustrup 对a once usual practice regarding user-controlled memory allocation and placement new 的看法略有不同——或者更具体地说,是关于神秘的“位置delete”。在书的教派。 11.2.4,Stroustrup 写道:
“placement
delete”操作符除了可能通知垃圾收集器删除的指针不再安全派生之外什么都不做。
这意味着良好的编程实践将遵循a call to placement delete 对析构函数的显式调用。
很公平。但是,没有比晦涩难懂的方式来调用placement 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()都将大小作为其第一个参数 并且分配的对象的大小是隐式提供的。new运算符使用的operator 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;“放置
delete”操作员除了可能通知一个 已删除指针不再安全的垃圾收集器 派生的。
然后,Stroustrup 继续讨论将放置new 与竞技场一起使用。他似乎没有再次提及安置delete。
【问题讨论】:
-
你能给出更完整的报价吗?您可能会将碰巧被称为“运算符”的 函数 与实际的 运算符 混淆。 C++ 中没有放置删除表达式。
-
C 中只有一种
delete expression,它不允许任何放置语法(只需查看标准中的语法产生)。这就是许多相当熟练的 C++ 程序员在说“C++ 中没有 placement delete expression”时的意思。也许在 C++14 或 C++17 中会有这种效果,但现在什么都没有。 -
@KerrekSB:我现在给出了更完整的报价。
-
有趣的是placement new 操作符也不做任何事情(嗯,它返回它的第二个参数)。所以我不知道他为什么特别呼吁删除这个位置。可能更有趣的是,
new表达式语法支持调用placement new,而delete表达式语法不支持调用placement delete(如问题中所述)。 Placement delete 只能被显式调用,或者当作为placement new 操作的结果运行的构造函数抛出异常时被隐式调用。 -
也许允许某种形式的直接调用构造函数(提供内存地址)会减少混乱。因为这就是放置 new/delete 的真正意义——调用构造函数和析构函数。没有任何东西被分配或释放。
标签: c++ placement-new