为什么在C ++中没有放置删除expression式?

为什么C ++没有放置删除直接对应于新的位置,即调用析构函数并调用适当的位置删除操作符?

例如:

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

operator delete在作为非成员或dynamic调度的静态成员函数中是唯一的。 具有虚拟析构函数的types执行从最派生的析构函数对其自己的delete的调用。

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

( 运行这个例子 。)

为了使用位置删除,析构函数必须以某种方式将附加parameter passing给operator delete

  • 解决scheme1:通过虚函数传递参数。 这需要为每个静态成员使用单独的虚拟析构函数,而使用不同参数的全局operator delete过载。
  • 解决scheme2:让虚拟析构函数返回一个指向调用者的函数指针,指定应该调用哪个operator delete 。 但是,如果析构函数确实查找,则会遇到需要多个虚函数定义为#1的相同问题。 某种抽象的重载集合将不得不被创build,调用者将解决。

你有一个非常好的点,这将是一个很好的除了语言。 在理论上, delete它改装成现有的delete语义甚至是可能的。 但大多数情况下我们不使用delete的全部function,只需使用伪析构函数调用,然后使用arena.release(p)

因为没有必要,因为我们已经有了ptr->~type();

可能是因为有语法显式调用一个析构函数没有释放(正如在你的问题),但没有原始内存的显式构造语法?

实际上,如果构造函数抛出一个exception,那么实际上会有一个放置删除,这个删除是使用放置new来“分配”的对象。

从维基百科 。

放置删除function是从放置新的expression式中调用的。 特别是,如果对象的构造函数抛出exception,则会调用它们。 在这种情况下,为了确保程序不会产生内存泄漏,将调用放置删除function。

全新的放置点就是将对象创build与内存pipe理分开。 所以在对象销毁期间将其绑回是没有意义的。
如果你的对象的内存来自堆,你需要相同的生命周期的对象和他们的内存只是使用operator newoperator delete ,也许覆盖它们,如果你想要的任何特殊的行为。
例如,在向量中放置新元素是很好的,它保留了大量的原始内存,并在内部创build和销毁对象,但是不释放内存。