Classes and class hierarchies
C.137
Use `virtual` bases to avoid overly general base classes
Reason
Allow separation of shared data and interface. To avoid all shared data to being put into an ultimate base class.
Example
struct Interface {
virtual void f();
virtual int g();
// ... no data here ...
};
class Utility { // with data
void utility1();
virtual void utility2(); // customization point
public:
int x;
int y;
};
class Derive1 : public Interface, virtual protected Utility {
// override Interface functions
// Maybe override Utility virtual functions
// ...
};
class Derive2 : public Interface, virtual protected Utility {
// override Interface functions
// Maybe override Utility virtual functions
// ...
};
Factoring out Utility makes sense if many derived classes share significant "implementation details."
Note
Obviously, the example is too "theoretical", but it is hard to find a small realistic example. Interface is the root of an interface hierarchy and Utility is the root of an implementation hierarchy. Here is a slightly more realistic example with an explanation.
Note
Often, linearization of a hierarchy is a better solution.
Enforcement
Flag mixed interface and implementation hierarchies.