`

c++ - virtual inheritance example 1

    博客分类:
  • c++
c++ 
阅读更多

we have discussed the virtual inhertiance in general in the post - C++ - virtual inheritance . In this post we are not going to discuss the theory but instead we are going to show you an example so that hopefully you can get a feel of how the virtual inheritance can be useful in real world.

 

Let's see we are devising libraries classes , the base classes is a Array<Type> class, and we want to add more functionality based on the base class.  So we are going to add some range checking abilility and then we are going to add a sorted functions. here is the code. 

 

/**
* virtual inheritance example
*  in this example, we are going to discuss the topic of multiple inheritance in an example 
*  
* 
*/
template <class Type>
class Array;

template <class Type>
ostream& operator << (ostream&, const Array<Type>&);

template <class Type>
class Array
{
	static const int ArraySize = 12;
public:
	explicit Array(int sz = ArraySize) { init (0, sz); }
	Array(const Type *ar, int sz) { init(ar, sz); } 
	Array(const Array &ia) { init(ia.ia, ia.size()); } 

	virtual ~Array() { delete[] ia; } 
	Array& operator= (const Array&);
	int size() { return _size; } 
	virtual void grow(); 

	virtual void print (ostream& = cout); 
	
	// program technique, in order to allow for better performance, 
	// since we are going to allow user to polymorphically 
	//retrieve the element at a specified index,
	// in order not to sacrifise the performance, we are making some helper class which is called 
	// at() which can be inlined. 
	Type at(int ix) const { return ia[ix]; } 
	virtual Type& operator[] (int ix) { return ia[ix]; }

	virtual void sort(int, int);
	virtual int find(Type );
	virtual Type min();
	virtual Type max();
protected:

	void swap(int , int);
	void init(const Type* , int);

	int _size;
	Type * ia;
private:

};


template <class Type>
class Array_RC : public virtual Array<Type> 
{
public: 
	// it is wrong to write as 
	//   Array_RC(int sz = ArraySize) : Array (sz)  {} any reference to the base template base class type specifier must be fully
	//     qualitified with its formal paramters list. 
	Array_RC(int sz = ArraySize) : Array<Type> (sz) {}
	Array_RC(const Array_RC& r) ;
	Array_RC(const Type * ar, int sz);
	Type& operator[] (int ix);

protected:
private:
};

#include <assert.h>

template <class Type>
Array_RC<Type>::Array_RC(const Array_RC<Type> &r) : Array<Type>(r) {}

template<class Type>
Array_RC<Type>::Array_RC(const Type * ar, int sz) : Array<Type>(ar, sz) {}

template <class Type>
Type& Array_RC<Type>::operator[] (int ix)
{
	assert(ix >= 0 && ix < Array<Type>::_size);
	return ia[ix];
}


template <class Type>
class Array_Sort : public virtual Array<Type> {
public:
	Array_Sort(const Array_Sort<Type> &);
	Array_Sort(const int sz = Array<Type>::ArraySize) : Array<Type>(sz) { clear_bit(); } 
	Array_Sort(const Type* arr, int sz) :Array<Type>(arr, sz) { sort(0, Aray<Type>::_size - 1); clear_bit(); } 

	Type operator[] (int ix) { 
		set_bit(); return ia[ix];
	}

	void print(ostream& os = cout ) { 
		check_bit(); Array<Type>::print(os); 
	}

	Type min() { check_bit(); return ia[0]; } 
	Type max() { check_bit(); return ia[Array<Type>::_size - 1]; } 
	
	bool is_dirty() const { return dirty_bit; }
	int find(Type); 
	void grow();
protected:
	void set_bit() { dirty_bit = true; } 
	void clear_bit() { dirty_bit = true; }
	void check_bit() { 
		if (dirty_bit) { 
			sort(0, Array<Type>::_size);
			clear_bit();
		}
	}
private:
};


template <class Type>
Array_Sort<Type>::Array_Sort(const Array_Sort<Type> &as) 
{
	// note: as.check_bit() does not work 
	// -- see explanation below
	if (as.is_dirty()) {
		sort(0, Array<Type>::_size - 1 ); 
	}
	clear_bit();
}

/** this is a very typical implemenation of the divide 2 search 
*/
template <class Type>
int Array_Sort<Type>::find(Type value) 
{
	int low = 0;
	int high = Array<Type>::_size - 1;
	check_bit();

	while (low <= high) {
		int mid = (low + high ) / 2;
		if (val == ia[mid]) return mid;
		if (val < ia[mid]) high = mid - 1;
		else low = mid + 1;
	}
	return -1;
}

/** 
* now we are going to make a class that shall inherits both the 
* Array_Sort and the Array_RC
* and the new class would be named as 
*   Array_RC_S
*
*/

template <class Type> 
class Array_RC_S : public Array_RC<Type>, public Array_Sort<Type>
{
public:
	Array_RC_S(int sz = Array<Type>::ArraySize) : Array<Type>(sz) {
		Sort(0, Array<Type>::_size - 1);
		clear_bit();
	}
	Array_RC_S(const Array_RC_S<Type> & rca)  : Array<Type>(rca)
	{
		sort(0, Array<Type>::_size -1 ); clear_bit(); 
	}

	Array_RC_S(const Type* arr, int sz) 
		: Array<Type> (rca)
	{
		sort(0, Array<Type>::_size - 1); 
		clear_bit();
	}

	Type& operator[] (int index) { 
		set_bit(); 
		return Array_RC<Type>::operator[] (index); 
	}

};
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics