多态性析构函数
如果要以多态方式使用类,并将派生实例存储为基本指针/引用,则其基类’析构函数应为 virtual
或 protected
。在前一种情况下,这将导致对象破坏检查 vtable
,根据动态类型自动调用正确的析构函数。在后一种情况下,禁用通过基类指针/引用销毁对象,并且只有在显式地将对象视为其实际类型时才能删除该对象。
struct VirtualDestructor {
virtual ~VirtualDestructor() = default;
};
struct VirtualDerived : VirtualDestructor {};
struct ProtectedDestructor {
protected:
~ProtectedDestructor() = default;
};
struct ProtectedDerived : ProtectedDestructor {
~ProtectedDerived() = default;
};
// ...
VirtualDestructor* vd = new VirtualDerived;
delete vd; // Looks up VirtualDestructor::~VirtualDestructor() in vtable, sees it's
// VirtualDerived::~VirtualDerived(), calls that.
ProtectedDestructor* pd = new ProtectedDerived;
delete pd; // Error: ProtectedDestructor::~ProtectedDestructor() is protected.
delete static_cast<ProtectedDerived*>(pd); // Good.
这两种实践都保证派生类的析构函数将始终在派生类实例上调用,从而防止内存泄漏。