模板

模板是泛型编程的基础,即与类型无关的逻辑代码。

利用模板机制可以显著减少冗余信息,能大幅度地节约程序代码,进一步提高面向对象程序的可重用性和可维护性。

模板是实现代码重用机制的一种工具,它可以实现类型参数化;

模板分为函数模板和类模板。

为了使用函数名相同,参数不同,返回值可同可不同的函数时,我们起初用了重载的方式。

#include<iostream>
using namespace std;

int add(int a,int b)
{
	return a+b;
}

double add(double a,double b)
{
	return a+b;
}

int main()
{
	cout<<"ret1="<<add(1,2)<<endl;
	cout<<"ret2="<<add(2.3,3.0)<<endl;
	getchar();
	return 0;
}

wKioL1bvstuDo-moAAAPLD_E0cI751.png

但是运用重载的方式写起来比较不方便,尤其是重载的函数较多时,为了解决这类问题,我们用函数模板来实现这种功能。

#include<iostream>
using namespace std;
template <class T>
T add(const T& a,const T& b)
{
        cout<<"type:"<<typeid(a).name()<<endl;   //显示类型
	return a+b;
}

int main()
{
	cout<<"ret1="<<add(1,2)<<endl;//还可以显示实例化,显示指定T为int,即add<int>(1,2)
	cout<<"ret2="<<add(2.3,3.0)<<endl;   //add<double>(2.3,3.0)
	getchar();
	return 0;
}

以上函数中函数参数类型都是相同的,当我们遇到形如:add(1,2.3);一个参数为int,一个参数为double型,此时我们可以这样定义:

template <class T1,class T2>
T add(const T1& a,const T2& b)
{
	return a+b;
}

当然,肯定有人会想,模板函数可以构成重载吗?    j_0057.gif答案是肯定的。

#include<iostream>
using namespace std;

int add(int a,int b)
{
	return a+b;
}

double add(double a,double b)
{
	return a+b;
}
template <class T>
T add(const T& a,const T& b)
{
	cout<<"type:"<<typeid(a).name()<<endl; 
	return a+b;
}

int main()
{
	cout<<"ret1="<<add(1,2)<<endl;
	cout<<"ret2="<<add(2.3,3.0)<<endl;
	getchar();
	return 0;
}

当模板构成重载,调用add的函数时,它会先调用非模板类的函数,性能比较高;而模板函数内部还得调用,有推演过程判断它是什么类型,效率上会有所降低。


2.模板类

对于普通函数来说,我们拿typedef重定义一个类型,当需要改的时候,需要将int改掉就可以了;

typedef int DataType;
 class SEQLIST
{
private:
    DataType *data;
};

而我们为了适应更多的类型,于是引入了模板类,我们这样定义,体现了其高度复用的优势:

template<class T>
class SeqList
{
private:
    T* data;
};

写一个模板类实现SeqList的动态顺序表吧:

#include<iostream>
using namespace std;

template <class T>
class SeqList
{
public:
	SeqList()
		:_data(NULL)
		,_size(0)
		,_capacity(0)
	{}
	SeqList(const SeqList<T>& s);
	SeqList<T>& operator=(const SeqList<T>& s);
	~SeqList()
	{
		if(_data != NULL)
		{
			delete[] _data;
		}
	}
	void CheckCapacity();
	void PushBack(const T& d);
	void PopBack();
	void PushFront(const T& d);
	void PopFront();
	void Print();
private:
	T *_data;
	int _size;
	int _capacity;
};
template <class T>
SeqList<T>::SeqList(const SeqList<T>& s)
{
	_data = new T[s._size*sizeof(T)];
	int i = 0;
	for(i = 0;i < s._size; i++)
	{
		_data[i] = s._data[i];
	}
	_size = s._size;
	_capacity = s._capacity;
}
template <class T>
SeqList<T>& SeqList<T>::operator=(const SeqList<T>& s)
{
	int i = 0;
	if(this == &s)
	{
		return *this;
	}
	_size = s._size;
	_capacity = s._capacity;
	delete _data;
	_data = new T[_capacity];
	for(i = 0; i < _size; i++)
	{
		_data[i] = s._data[i];
	}
	return *this;
}
template <class T>
void SeqList<T>::CheckCapacity()
{
	if(_size == _capacity)
	{
		T* tmp = new T[_capacity*2+3];
		//memcpy(tmp,_data,_size*sizeof(T));
		int i = 0;
		for(i = 0; i < _size; i++)
		{
			tmp[i] = _data[i];
		}
		delete[] _data;
		_data = tmp;
		_capacity = _capacity*2+3;
	}
}
template <class T>
void SeqList<T>::PushBack(const T& d)
{
	CheckCapacity();
	_data[_size] = d;
	_size++;
}
template <class T>
void SeqList<T>::PopBack()
{
	CheckCapacity();
	_size--;
}

template <class T>	
void SeqList<T>::PushFront(const T& d)
{
	int i ;
	CheckCapacity();	
	for(i = _size; i > 0; i--)
	{
		_data[i] = _data[i-1];
	}
	_data[0] = d;
	_size++;
}

template <class T>
void SeqList<T>::PopFront()
{
	int i;
	CheckCapacity();
	for(i = 0; i < _size; i++)
	{
		_data[i] = _data[i+1];
	}
	_size--;
}
template <class T>
void SeqList<T>::Print()
{
	int i = 0;
	for(i = 0; i < _size; i++)
	{
		cout<<_data[i]<<" ";
	}
	cout<<endl;
}

int main()
{
	SeqList<int> seq;
	SeqList<int> seq1;
	cout<<"seq:"<<endl;
	cout<<"尾插1234"<<endl;
	seq.PushBack(1);
	seq.PushBack(2);
	seq.PushBack(3);
	seq.PushBack(4);
	seq.Print();
	cout<<"尾删"<<endl;
	seq.PopBack();
	seq.Print();
	cout<<"头删"<<endl;
	seq.PopFront();
	seq.Print();
	cout<<"seq2:"<<endl;
	SeqList<int> seq2(seq);
	seq2.Print();
	cout<<"头插567"<<endl;
	seq.PushFront(5);
	seq.PushFront(6);
	seq.PushFront(7);
	seq.Print();
	seq1 = seq;
	cout<<"seq1:"<<endl;
	seq1.Print();
	getchar();
	return 0;
}

模板就说到这里啦,有好的建议还希望大家提出来,欢迎来访哦。i_f01.gifi_f01.gif

你可能感兴趣的:(函数模板,类模板)