为什么c++中没有位置删除表达式

Why there is no placement delete expression in C++?

本文关键字:位置 删除 表达式 c++ 为什么      更新时间:2023-10-16

为什么c++没有直接对应于位置new的位置delete,即调用析构函数并调用适当的位置delete操作符?

例如:

MyType *p = new(arena) MyType;
...
//current technique
p->~MyType();
operator delete(p, arena);
//proposed technique
delete(arena) p;

operator delete是唯一的动态分派的非成员或静态成员函数。具有虚析构函数的类型从最派生的析构函数执行对自己的delete的调用。

struct abc {
    virtual ~abc() = 0;
};
struct d : abc {
    operator delete() { std::cout << "goodbyen"; }
};
int main() {
    abc *p = new d;
    delete p;
}

(运行本例)

如果要与位置删除一起工作,析构函数必须以某种方式将额外的参数传递给operator delete

  • 方案一:通过虚函数传递实参。这需要为每个静态成员和具有不同参数的全局operator delete重载单独的虚析构函数。
  • 解决方案2:让虚析构函数返回一个指向调用者的函数指针,指定应该调用什么operator delete。但是,如果析构函数进行查找,就会遇到与#1相同的问题,即需要定义多个虚函数。必须创建某种抽象的重载集,由调用者来解析。

你有一个非常好的观点,这将是对语言的一个很好的补充。从理论上讲,将其改造成delete的现有语义甚至是可能的。但是大多数情况下,我们不会使用delete的全部功能,使用伪析构函数调用后面跟着arena.release(p)之类的东西就足够了。

可能是因为有显式调用析构函数而不释放的语法(就像你的问题一样),但没有在原始内存中显式构造的语法?

实际上,如果构造函数抛出异常,则存在一个放置delete操作,该操作由实现调用,用于使用放置new"分配"的对象。

从维基百科。

位置delete函数从位置new表达式调用。特别是,如果对象的构造函数抛出异常,则调用它们。在这种情况下,为了确保程序不会引起内存泄漏,将调用位置删除函数。

放置new的全部意义在于将对象创建与其内存管理分开。因此,在对象销毁期间将其绑定是没有意义的。如果你的对象的内存来自堆,并且你希望对象和它们的内存具有相同的生命周期,那么使用operator newoperator delete,如果你想要任何特殊的行为,可能会覆盖它们。
new的位置很好,例如在vector中,它保留了大量的原始内存,并在其中创建和销毁对象,但不释放内存。