c++ type of inheritance

There are 3 types of inheritances in classes inheritance in C++; they are 

 

  • public inheritance 
  • protected inheritance
  • protected inheritance

 

as for the synonym of the type of inheritances, public inheritance is also know as type inheritance, while the private  inheritance is also know as implementation inheritancfe. 

 

 

A public derivation is refered to as type inhertitance, the dervied class is a subtype of the bse classes; it overrides the implementation of all type-specific member funcitons. of the base class while inheriting those that are shared.  The derived class in general reflects is-a relationship

 

While we know a lots can be found abou the public inheritance, here we are not going into details further. 

 

 

A private derivation is refered to as implementation inheritance, the derived class does not support the public interface of hte base directly. rather, it wishes to reuses the implementation of the base class while providing its own interface. To illustrate the issues involved, let's implements a PeekbackStack. 

 

Let's see an examle. 

 

suppose that we are subclass a IntArray class (a custom class) and provide additional functionality such as the ability to peek the back of the stack, which we call the subclass PeekbackStack.

 

for illustration purpose, this is the simplified version of IntArray code.

 

class IntArray
{
public:
	IntArray(int size) : _size(size) {
		init(size, 0);
	}
	IntArray(const IntArray & rhs) { 
		init(rhs.size(), rhs.ia);
	}
	int size() const { return _size; }
	int& operator[](int index) { return ia[index]; }

	virtual ~IntArray() { 
		delete[] ia;
	}
private:
	void init(int sz, int * array_) { 
		_size = sz;
		ia = new int[_size];
		for (int i = 0; i < _size; ++i) {
			if (! array_)
				ia[i] = 0;
			else ia[i] = array_[i];
		}
	}
protected:
	int _size;
	int *ia;
};

 

if you are using the public inheritance, you might implement the code as follow. 

 

 

class PeekbackStack : public IntArray
{
private:
	const int static bos = -1;
public:
	explicit PeekbackStack(int size) : IntArray(size), _top(bos) { }

	bool empty() const { return _top == bos;  } 
	bool full() const { return _top == size() - 1; }
	bool top() const { return _top; } 

	int pop() { 
		if (empty()) {
			/* handle error condiiton */
			return ia[_top --];
		}
	}
	void push(int value ) {
		if (full() ) {
			/* handle error condition */
			ia[++_top] = value; 
		}
	}
	bool peekback(int index, int & value) const;

private:
	int _top;
};

inline bool
	PeekbackStack::peekback(int index, int & value) const { 
		if (empty() ) {
			/* handle error condition */
		}
		if (index < 0 || index > _top) 
		{
			value = ia[_top];
			return false; 
		}
		value = ia[index];
		return true;
}
 

 

This is all good, except that there is a by-prpduct, whereas , Program using the new PeekbackStack class may also make inappropriate use of its IntArray base class public interface, for example. 

 

extern void swap(IntArray&, int, int);
Peekbackstack is(1024);

// oops: unexpected misuse of the PeekbackStack
swap(is, i , j);
is.sort();
is[0] = is[512];

So, the public inheritance represents a is-a relationship, while reflected back in our case, we can see that PeekbackStack is a special kind of IntArray, so you can expect that the operation that is applicable to PeekbackStack as well.  so we can see that public inheritance is not the best fit for our case, what we want to is to restrict the  user to the interfaces that is defined by us. 

 

So how to address that, here comes the private inheritance.  Let's see how we impl the private inheritance through the use of private inheritance

 

 

the solution is quite easy, you just change the public keyword with the private in the class derivation list. 

 

 

class PeekbackStack: private IntArray { ... }
 

 

as a side note, a private base class reflects a form of inheritance that is not based on subtype relationship. The entire public interface of the base class becomes private in the derived class. Each of the preceding misuses of a PeekbackStack class instance is now illegal except witin in friend and member functions of the derived class.

 

 

Thus, it may as well deserve to talk about composition versus inheritance as far as we have private inheritance covered.  

 

Since, after all with the private inheritance, we have achieved a kind of has-as relationship with regards to the IntArray classes. 

 

Here is the new PeekbackStack implementaion with Composition pattern .

 

 

class PeekbackStack 
{
private: 
	const int static bos = -1;
public:
	explicit PeekbackStack (int size):	stack (size), _top(bos) {}

	bool empty() const { return _top == bos; }
	bool full() const { return _top == stack.size() - 1; }
	int top() const { return _top; } 

	int pop() {
		if (empty() ) {
			 // handling error 
		}
		return stack[_top -- ];
	}

	void push(int value) 
	{
		if ( full() ) {
			// handle error condition
		}
		stack[++_top] = value; 
	}

	bool peekback(int index, int & value) const; 

private: 
	int _top;
	IntArray stack;
};

 

 

so you may wonder when to use private inheritance and when to use the composition by references/value?

 

so this is a very good guidelines as whether to use composition or private inheritance in a class design in  in which a has-a relationship exists

 

 

  • If we wish to override any of the virtual functions of a class, we must inherit from it privately.
  • If we wish to allow the class to refer to one of a hierarchy of possible types, we must use composition by reference
  • If as with our PeekbackStack class, we wish simply to reuse the implementation, composition by value is to be preferred over inheritance. If a lazy allocation of the object is desired, composition by reference (useing a pointer) is the generally preferred design choice. 

 

 

So we have covered the private and public inhertance, let's see why we have protected inheritance...

 

Before we introduce the protected inheritance, let's first examing the "exemping individual members"... since with private inhertiance, protected and public members are now all becomes private, in our example, you cannot allow the client to access the IntArray::size() method (which should be the same if the PeekbackStack class need to provide a size() method).

 

 

So what you can do is as follow.

class PeekbackStack : private IntArray
{
//....
public:
	
	// you can allow the client to access the IntArray size method by exempting the size method in the public section 
	using IntArray::size;

	// you can allow further subsequent derivation access to the protected members. you can exempt individual members in the protected section
protected: 
	using IntArray::_size;
	using IntArray::ia;
//....
};

 

However, this is tedious work and further, suppose that if we change the hierarchy so that 

 

Stack inherits IntArray, => PeekbackStack inherits Stack, if we were using the private inheritancfe, we cannot allow the PeekbackStack to override some members, while protected inheritaince provides a perfect balance/compromise. 

 

so if you do 

class Stack : protected IntArray { ... }

 then it you can easilty do 

class PeekbackStack : public Stack { ... } 
 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值