C++ – why are concrete types rarely useful as bases for further derivation


I read "Concrete types are rarely useful as bases for further derivation"———— Stroustrup p. 768

How to interpret this? Does it mean that we should get derived class from the base class with pure virtual function? However, I see a lot of code with derived class derived from concrete types.

Can anyone help me out?

Best Solution

Suppose you created a derived class, then replaced every instance of the base class in your program with that derived class. Did the resulting program behave the same? If not, then you have introduced some gotchas. These gotchas will probably be accounted for in the case of a class designed for inheritance (e.g. I've seen some classes designed for inheritance that actually have functions to check if other functions are implemented to allow for the case of them not even existing, e.g. file i/o classes that might be missing seek functionality). Since an abstract class is always going to have been designed with inheritance in mind but a concrete class might not, this could be unsafe.

The explanation above talks about the case where the resulting derived class is not fully compatible with the base class, which is dangerous. But what if it is fully compatible? In this case, some of the potential justifications for using inheritance (instead of composition) fall apart. We don't have any virtual functions or protected members (if we do, then I assume the class was designed for inheritance). Still, using inheritance in this case is probably pretty safe, though ensuring it really is fully compatible is tough. I'd rather use composition and be safe.

The term for what I was talking about above is the Liskov Substitution Principle. A shorter explanation would be that in most cases, a derived class of a class not designed for inheritance will either violate Liskov's Substitution Principle or will not be able to accomplish anything useful that could not have been accomplished using composition instead.