Let's stay with the example of the vector. A vector is just a container of T
s. Now let's say you want to build a type that behaves just like a vector, but adds some additional runtime checks. I don't have my copy of TC++PL at hand right now, so let's just make up a constraint: For example, let's say your vector is only allowed to hold even numbers. Attempting to insert an odd number will result in a runtime error. Let's call this new class even_vector
and the version without the runtime checks base_vector
.
even_vector
provides stronger runtime guarantees than base_vector
: It is guaranteed that all of its elements are even.
Assuming that your base_vector
is designed to work nice as a base class (which std::vector
typically does not), you might now be tempted to use public inheritance to implement even_vector
in terms of base_vector
. After all, the functionality is the same, you simply have some additional runtime checks in the even_vector
case on top of the functionality provided by base_vector
. However, if you were to use public inheritance here, you would violate the Liskov Substitution Principle: You cannot use an even_vector
wherever you use a base_vector
. In particular, the even_vector
will break in cases where you are inserting odd numbers into a base_vector
. This is bad, as now all code that is written for base_vector
must account for the fact that some of the base_vector
s cannot deal with odd numbers.
With private inheritance you do not have this problem: Here the fact that even_vector
inherits from base_vector
is a detail of the implementation. Clients cannot use even_vector
where a base_vector
is expected, so the problem from above does not occur, but we still get the benefits of code reuse.
That being said, using private inheritance for code reuse is a practice that is discouraged by many. An arguably better way would be to use composition here instead, that is, add a private base_vector
member to even_vector
instead. The advantage of that approach is that it severely reduces coupling between the two classes, as even_vector
is no longer able to access any non-public parts of base_vector
.