Virtual and Protected Destructors

suggest change

A class designed to be inherited-from is called a Base class. Care should be taken with the special member functions of such a class.

A class designed to be used polymorphically at run-time (through a pointer to the base class) should declare the destructor virtual. This allows the derived parts of the object to be properly destroyed, even when the object is destroyed through a pointer to the base class.

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

If the class does not need to be polymorphic, but still needs to allow its interface to be inherited, use a non-virtual protected destructor.

class NonPolymorphicBase {
public:
    //    some methods

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

private:
    //    etc.
};

Such a class can never be destroyed through a pointer, avoiding silent leaks due to slicing.

This technique especially applies to classes designed to be private base classes. Such a class might be used to encapsulate some common implementation details, while providing virtual methods as customisation points. This kind of class should never be used polymorphically, and a protected destructor helps to document this requirement directly in the code.

Finally, some classes may require that they are never used as a base class. In this case, the class can be marked final. A normal non-virtual public destructor is fine in this case.

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

private:
    //    etc.
};

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:


Special member functions:
* Virtual and Protected Destructors

Table Of Contents
8 Arrays
11 Loops
39 Streams
51 Unions
56 Lambdas
60 SFINAE
62 RAII
65 Special member functions
67 Sorting
84 RTTI
87 Scopes
104 Profiling
107 Recursion
117 Iteration
125 Alignment
134 Semaphore
136 Debugging
139 Mutexes
142 decltype