1. 程式人生 > >C++——類模板相關知識

C++——類模板相關知識

本文章將對類模板的相關內容進行說明,如有不足,歡迎指正。

類模板的知識點可以分為以下幾點:

 1.  類模板
 2. 類模板中成員方法的模板
 3. 類模板中成員方法的模板的特例化
 4. 拷貝建構函式的模板和特例化

類模板具有以下特徵:

1. 類模板如果不使用,則不會進行例項化

2. 類模板中成員方法的模板特例化不允許在類外實現,因為其絕對依賴於模板

詳細內容請參考以下程式碼

程式碼示例1:

//用類模板實現陣列的增刪改查
template <typename T>
class Carry
{
private:
	T* _arr;
	int _len;
	int _sizeVal;

public:
	Carry(int resize = 2) //resize是給的預設值
	{
		cout<<"Carry(int resize = 2)"<<endl;
		_arr = new T [resize];
		_len = resize;
		_sizeVal = 0;
	}

	~Carry()
	{
		cout<<"~Carry()"<<endl;
		delete []_arr;
	}

	Carry(const Carry &src)
	{
		cout<<"Carry(const Carry &src)"<<endl;
		_arr = new T[src._len];
		_sizeVal = src._sizeVal;
		_len = src._len;
		copyFrom(src);
	}

	//深拷貝時把原來空間裡的值拷貝到新空間裡
	void copyFrom(const Carry &src)
	{
		cout<<"void copyFrom(const Carry &src)"<<endl;
		for(int i=0; i<src._sizeVal; i++)
		{
			_arr[i] =  src._arr[i];
		}
	}

	Carry &operator = (const Carry &src)
	{
		cout<<"Carry &operator = (const Carry &src)"<<endl;
		if(&src == this)
		{
			return *this;
		}
		if(_arr != NULL)
		{
			delete []_arr;
		}

		_arr = new T[src._len];
		_sizeVal = src._sizeVal;
		_len = src._len;
		copyFrom(src);
	}

	void pushBack(T val)
	{
		cout<<"void pushBack(T val)"<<endl;
		if(isFull())
		{
			reSize();
		}
		//_arr[_sizeVal] = val;
		//_sizeVal ++;
		_arr[_sizeVal++] = val;
	}

	/*
	void insert(int sit, T val)
	{
		if(isFull())
		{
			reSize();
			return false;
		}
		_len ++;
		return true;
	}
	*/
	bool popBack()
	{
		cout<<"bool popBack()"<<endl;
		if(isEmpty())
		{
			return false;
		}
		_sizeVal --;
		return true;
	}

	/*
	bool deleteSit(int sit)
	{
		if(isEmpty)
		{
			return false;
		}
		sit -= 1;
		_len --;
		return true;
	}
	*/

	T getBack()
	{
		cout<<"T getBack()"<<endl;
		if(isEmpty())
		{
			return T();
		}
		//return _arr[_sizeVal];
		//_sizeVal--;
		return _arr[_sizeVal--];
	}

	
	void show();
/*
	{
		cout<<"void show()"<<endl;
		for(int i=0; i<_sizeVal; i++)
		{
			cout<<_arr[i]<<"  ";
		}
		cout<<endl;
	}
*/
/*
	int find(T val);
	{
		cout<<"int find(T val)"<<endl;
		for(int i=0; i<_sizeVal; i++)
		{
			if(arr[i] == val)
			{
				return i;
			}
		}
		return -1;
	}
*/

	//類模板要帶型別引數
	template<typename U>
	int find(U val);
/*
	{
		cout<<"template<typename U> int find(U val)"<<endl;
		for(int i=0; i<_sizeVal; i++)
		{
			if(arr[i] == val)
			{
				return i;
			}
		}
		return -1;
	}
*/

/*	template<>
	int find<char*>(char* val);
	{
		cout<<"	template<> int find<char*>(char* val)"<<endl;
		for(int i=0; i<_len; i++)
		{
			if(strcmp(arr[i], val) == 0)
			{
				return i;
			}
		}
		return -1;
	}
*/

	bool isFull()
	{
		cout<<"bool isFull()"<<endl;
		return _sizeVal == _len;
	}

	bool isEmpty()
	{
		cout<<"bool isEmpty()"<<endl;
		return _sizeVal == 0;
	}

	void reSize()
	{
		cout<<"void reSize()"<<endl;
		T *tmp = new T[_len + (_len >> 1)];

		for(int i=0; i<_len; i++)
		{
			tmp[i] = _arr[i];
		}
			delete[]_arr;
			_arr = tmp;
			_len = _len + (_len >> 1);
	}
};

//在類外實現的類模板
template<typename T>
void Carry<T>::show()
{
	for(int i=0; i<_sizeVal; i++)
	{
		cout<<_arr[i]<<"  ";
	}
	cout<<endl;
}

template<typename T>
template<typename U>
int Carry<T>::find(U val)
{
	for(int i=0; i<_sizeVal; i++)
	{
		if(_arr[i] == val)
		{
			return i;
		}
	}
	return -1;
}

/*
template<typename T>
template<>
int Carry<T>::find<char*>(char* val)
{
	for(int i=0; i<_sizeVal; i++)
	{
		if(strcmp(arr[i], val) == 0)
		{
			return i;
		}
	}
	return -1;
}
*/

int main()
{
	Carry<int> arr1;
	for(int i=0; i<10; i++)
	{
		arr1.pushBack(i);
	}
	int sit = arr1.find(10);
	cout<<sit<<endl;
	arr1.show();

	Carry<char*> arr2;
	arr2.pushBack("hello");
	arr2.pushBack("world");
	arr2.pushBack("sweetygirl");
	char str[] = {'s','w','e','e','t','y','g','i','r','l','\0'};
	sit = arr2.find(str);
	cout<<sit<<endl;
	arr2.show();

	return 0;
}