多态性析构函数

如果要以多态方式使用类,并将派生实例存储为基本指针/引用,则其基类’析构函数应为 virtualprotected。在前一种情况下,这将导致对象破坏检查 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.

这两种实践都保证派生类的析构函数将始终在派生类实例上调用,从而防止内存泄漏。