虚拟和受保护的析构函数

设计为继承的类称为 Base 类。应该注意这类特殊成员的职能。

设计为在运行时以多态方式使用的类(通过指向基类的指针)应该声明析构函数 virtual。这允许正确地销毁对象的派生部分,即使通过指向基类的指针销毁对象也是如此。

class Base {
public:
    virtual ~Base() = default;

private:
    //    data members etc.
};

class Derived : public Base { //  models Is-A relationship
public:
    //    some methods

private:
    //    more data members
};

//    virtual destructor in Base ensures that derived destructors
//    are also called when the object is destroyed
std::unique_ptr<Base> base = std::make_unique<Derived>();
base = nullptr;  //    safe, doesn't leak Derived's members

如果类不需要是多态的,但仍需要允许继承其接口,请使用非虚拟的 protected 析构函数。

class NonPolymorphicBase {
public:
    //    some methods

protected:
    ~NonPolymorphicBase() = default; //    note: non-virtual

private:
    //    etc.
};

这样的类永远不会通过指针销毁,从而避免由于切片导致的无声泄漏。

这种技术特别适用于设计为 private 基类的类。这样的类可以用于封装一些常见的实现细节,同时提供 virtual 方法作为定制点。这种类永远不应该以多态方式使用,而 protected 析构函数有助于直接在代码中记录这一要求。

最后,某些类可能要求它们从不用作基类。在这种情况下,该类可以标记为 final。在这种情况下,正常的非虚拟公共析构函数很好。

class FinalClass final {  //    marked final here
public:
    ~FinalClass() = default;

private:
    //    etc.
};