C++中没有placement delete

placement new即带有额外参数的new表达式: T *p = new(string{"hi"}) T;。该表达式会调用相应的operator new来获得内存地址,然后再上面调用构造函数。那个额外的参数一般用来指定内存地址或内存分配器,少数情况下用来追踪。

比较奇怪的是竟然没有对应的placement delete,即 delete(string{"end"}) ptr; 这样的代码是不合法的。C++之父给出的答案是C++的类型系统无法推断与ptr相关联的参数,容易被误用,如果需要的话可以手工构造一个destory函数来模拟。但我觉得容易被误用这个理由很牵强,因为毕竟需要显式手工调用,而且placement delete显然比destory函数含义更明显,也更方便。

但这样也有一个好处:可以把应该在placement delete中实现的逻辑放在普通的operator delete中,这样就能统一通过 delete ptr; 来删除,也方便了智能指针类的实现。

虽然没有placement delete,但与placement new 的operator new对应的operator delete还是要定义的,它会在构造函数抛出异常时自动调用,避免内存泄露。

另外operator delete不能声明为虚函数,但仍能在通过基类指针删除子类对象时调用正确的operator delete,原因在于operator delete函数是在析构函数内部调用的,只要析构函数是虚函数operator delete就能正确调用。

还意外发现一点:子类析构函数调用父类析构函数前,对象的虚表指针会先被修正为指向父类的虚表。因此调用一次子类对象的析构函数后,再次调用析构函数会发现,它只会调用父类的析构函数了。

发表评论

电子邮件地址不会被公开。 必填项已用*标注