Consider making virtual functions non-public, and public functions non-virtual

In base classes with a high cost of change (particularly ones in libraries and frame-works): Prefer to make public functions non-virtual. Prefer to make virtual functions private, or protected if derived classes need to be able to call the base versions.

A public virtual function inherently has two different and competing responsibilities:

  • It specifies interface: Being public, it is directly part of the interface the class presents to the rest of the world.

  • It specifies an implementation detail: Being virtual, it provides a hook for derived classes to replace the base implementation of that function; it is a customization point.

In general, one function cannot fulfill both responsibilities perfectly. Here is an example, where both responsibilities are separated:

class A {
public:
    something(/* args */) {
        // pre-conditions, e.g. check args; may be added later
        doSomething(/* args */);
        // post-conditions, e.g. check internal state; may be added later
    }
protected:
    virtual doSomething(/* args */) = 0; // the customization point
};

Note

This advice does not apply to destructors. Destructors should be public and virtual, if want to be able to delete an instance of a derived class with a base pointer.