Use class hierarchies to represent concepts with inherent hierarchical structure (only)
Reason
Direct representation of ideas in code eases comprehension and maintenance. Make sure the idea represented in the base class exactly matches all derived types and there is not a better way to express it than using the tight coupling of inheritance.
Do not use inheritance when simply having a data member will do. Usually this means that the derived type needs to override a base virtual function or needs access to a protected member.
Example
class DrawableUIElement {
public:
virtual void render() const = 0;
// ...
};
class AbstractButton : public DrawableUIElement {
public:
virtual void onClick() = 0;
// ...
};
class PushButton : public AbstractButton {
void render() const override;
void onClick() override;
// ...
};
class Checkbox : public AbstractButton {
// ...
};
Example, bad
Do not represent non-hierarchical domain concepts as class hierarchies.
template<typename T>
class Container {
public:
// list operations:
virtual T& get() = 0;
virtual void put(T&) = 0;
virtual void insert(Position) = 0;
// ...
// vector operations:
virtual T& operator[](int) = 0;
virtual void sort() = 0;
// ...
// tree operations:
virtual void balance() = 0;
// ...
};
Here most overriding classes cannot implement most of the functions required in the interface well. Thus the base class becomes an implementation burden. Furthermore, the user of Container cannot rely on the member functions actually performing meaningful operations reasonably efficiently; it might throw an exception instead. Thus users have to resort to run-time checking and/or not using this (over)general interface in favor of a particular interface found by a run-time type inquiry (e.g., a dynamic_cast).
Enforcement
- Look for classes with lots of members that do nothing but throw.
- Flag every use of a non-public base class
Bwhere the derived classDdoes not override a virtual function or access a protected member inB, andBis not one of the following: empty, a template parameter or parameter pack ofD, a class template specialized withD.