Item 24. Uses and Abuses of
Inheritance
Difficulty: 6
"Why inherit?"
Inheritance is often
overused, even by experienced developers. Always minimize coupling.
If a class relationship can be expressed in more than one way, use
the weakest relationship that's practical. Given that inheritance
is nearly the strongest relationship you can express in C++ (second
only to friendship), it's only really appropriate when there is no
equivalent weaker alternative.
In this Item, the
spotlight is on private inheritance, one real (if obscure) use for
protected inheritance, and a recap of the proper use of public
inheritance. Along the way, we will create a fairly complete list
of all the usual and unusual reasons to use inheritance.
The following template provides list-management
functions, including the ability to manipulate list elements at
specific list locations.
// Example 1
//
template <class T>
class MyList
{
public:
bool Insert( const T&, size_t index );
T Access( size_t index ) const;
size_t Size() const;
private:
T* buf_;
size_t bufsize_;
};
Consider the following code, which shows two
ways to write a MySet class in terms of MyList.
Assume that all important elements are shown.
// Example 1(a)
//
template <class T>
class MySet1 : private MyList<T>
{
public:
bool Add( const T& ); // calls Insert()
T Get( size_t index ) const;
// calls Access()
using MyList<T>::Size;
//...
};
// Example 1(b)
//
template <class T>
class MySet2
{
public:
bool Add( const T& ); // calls impl_.Insert()
T Get( size_t index ) const;
// calls impl_.Access()
size_t Size() const; // calls impl_.Size();
//...
private:
MyList<T> impl_;
};
Give these alternatives some thought, and
consider the following questions.
-
Is there any
difference between MySet1 and MySet2?
-
More generally,
what is the difference between
nonpublic inheritance and containment? Make as comprehensive a list
as you can of reasons why you would use inheritance instead of
containment.
-
Which version
of MySet would you prefer—MySet1 or
MySet2?
-
Finally, make
as comprehensive a list as you can of reasons why you would use
public inheritance.
|