成员operator new
/delete
可能有助于从基类中删除不需要的自定义分配,例如,如果基类不打算扩展。但是基础要么需要一个虚拟析构函数,要么基础对象永远不能是delete
.
实际上,operator delete
需要独立于重载的虚拟析构函数调度。该功能的存在可能是为了支持多重继承,而动态查找正确的成员operator delete
只是一个副作用。
规则很简单,最派生对象的虚拟析构函数调用operator delete
. 主要原因是传递正确的最衍生指针和大小。上下文还使程序能够动态地找到正确的释放函数只是一个令人愉快的副作用。
因此,动态调度可能有也可能没有有用的应用程序delete
,但绝对没有专门的机制让它工作。
简单演示:
struct pad {
int x;
virtual ~pad() {}
};
struct b {
int x;
};
struct vb {
int x;
virtual ~vb() {}
};
struct d : pad, b, vb {};
void operator delete( void *p ) {
std::cout << "free " << p << '\n';
}
int main() {
std::cout << "With virtual destructor:\n";
d *p = new d;
std::cout << "allocate " << p << ", delete " << static_cast< vb * >( p ) << '\n';
delete static_cast< vb * >( p );
std::cout << "With plain destructor:\n";
p = new d;
std::cout << "allocate " << p << ", delete " << static_cast< b * >( p ) << '\n';
delete static_cast< b * >( p );
}