Uses And Abuses of Inheritance

Use inheritance wisely. If you can express a class relationship using containment/delegation alone, you should always prefer that. If you need inheritance but aren't modeling IS-A, use nonpublic inheritance. If you don't need the combinative power of multiple inheritance, prefer single inheritance. Large inheritance hierarchies, in general, and deep ones, in particular, are confusing to understand and therefore difficult to maintain. Inheritance is a design-time decision and trades off a lot of run-time flexibility.


// 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_;
};

// Example 1(c): Generic containment 
//
template <class T, class Impl = MyList<T> >
class MySet3
{	
	
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:
	Impl impl_;	
};


// 1.We need to override a virtual function.
// 2.We need access to a protected member.
// 3.We need to construct the used object before, or destroy it after, another base subobject.
// 4.We need to share a common virtual base class or override the construction of a virtual base class.
// 5.We benefit substantially from the empty base class optimization
// Example 2: Sometimes you need to inherit 


//
class Base
{	
public:	
	virtual int Func1();
	
protected:	
	bool Func2();

private:
	bool Func3(); // uses Func1	
};

// Example 2(a) 
//
class Derived : private Base // necessary?
{	
public:	
	int Func1();	
	// ... more functions, some of which use	
	//     Base::Func2(), some of which don't ...
};
// Example 2(b) 
//
class DerivedImpl : private Base
{	
public:	
	int Func1();	
	// ... functions that use Func2 ...		
};

class Derived
{
	
	// ... functions that don't use Func2 ...		
private:		
	DerivedImpl impl_;		
};

// Never use public inheritance when nonpublic inheritance will do



發佈了42 篇原創文章 · 獲贊 0 · 訪問量 8607
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章