为什么C ++没有直接对应于placement new的展示位置删除,即调用析构函数并调用相应的展示位置删除运算符?
例如:
MyType *p = new(arena) MyType;
...
//current technique
p->~MyType();
operator delete(p, arena);
//proposed technique
delete(arena) p;
答案 0 :(得分:22)
operator delete
在作为动态分派的非成员或静态成员函数时是唯一的。具有虚析构函数的类型从最派生的析构函数执行对其自己的delete
的调用。
struct abc {
virtual ~abc() = 0;
};
struct d : abc {
operator delete() { std::cout << "goodbye\n"; }
};
int main() {
abc *p = new d;
delete p;
}
为了使用放置删除,析构函数必须以某种方式将其他参数传递给operator delete
。
operator delete
重载使用单独的虚拟析构函数。operator delete
。但是如果析构函数执行查找,则会遇到需要多个虚函数定义为#1的相同问题。必须创建某种抽象的重载集,调用者才能解析它。你有一个非常好的观点,它将是一种很好的语言补充。理论上,将其改编为delete
的现有语义甚至可能是可能的。但是大多数时候我们不使用delete
的全部功能,只需使用伪析构函数调用,然后使用类似arena.release(p)
的内容。
答案 1 :(得分:21)
因为我们已经有ptr->~type();
答案 2 :(得分:8)
可能是因为有没有解除分配显式调用析构函数的语法(与你的问题完全相同),但原始内存中没有显式构造的语法?
答案 3 :(得分:7)
实际上有一个放置删除,如果构造函数抛出异常,则使用placement new“分配”的对象的实现调用。
从展示位置新表达式调用展示位置删除功能。特别是,如果对象的构造函数抛出异常,则调用它们。在这种情况下,为了确保程序不会导致内存泄漏,调用放置删除功能。
答案 4 :(得分:2)
新的放置点是将对象创建与内存管理分开。所以在对象破坏期间将它绑回来是没有意义的
如果对象的内存来自堆,并且您希望对象及其内存具有相同的生命周期,请使用operator new
和operator delete
,如果您想要任何特殊行为,可能会覆盖它们。
例如,vector中的Placement是很好的,它可以保留大量的原始内存,并在其中创建和销毁对象,但不释放内存。