模板函数与模板类

来源:互联网 发布:网络打印机打印错误 编辑:程序博客网 时间:2024/06/07 00:13

模板

模板是泛型编程的基础。所谓泛型编程就是编写与类型⽆关的逻辑代码,是⼀种复⽤的⽅式。

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

1.模板函数

假设现在要实现一个比较数是否相等的重载函数,在以前都要写不同类型的函数,例子如下:

bool IsEqual (int left, int right){return left == right;}bool IsEqual (const string& left , const string& right){return left == right;}
以上是比较了两个整型和两个字符型的函数,这样进行了重载,但是不能比较其他的类型的函数,若想比较其他的类型,则需要重新再写别的函数,这些重复性的工作我们都可以用模板函数进行处理。

函数模板格式:
 template <class 形参名1, class 形参名2, class 形参名n>
返回类型 函数名(参数列表)
 {...}

模板形参的定义既可以使⽤class,也可以使⽤typename,含义是相同的。

现在要解决比较两个数的函数就可以用模板函数来解决,代码如下:

template<typename T>bool IsEqual (const T& left , const T& right ){return left == right;}void test1 (){string s1 ("s1"), s2("s2" );cout<<IsEqual (s1, s2)<<endl ;cout<<IsEqual (1,1)<<endl;}
模板函数就是自己写一份与类型无关的代码,编译器自动通过调用时进行推演,推演出适合整型比较的函数和适合字符型比较的函数,这个过程叫做模板函数的实例化。

具体如下图所示:

在这个过程中,当运行到IsEqual(s1,s2)时,编译器根据传递的参数自动推演出模板形参的类型,从而得出右侧第二个函数,进而调用推演出的函数。

同时,在汇编语言中也可以清晰地看到对于不同参数类型的函数,编译器推演出的函数类型也不相同。

以下是汇编角度看模板函数的推演:

注意:

当出现调用时模板参数不匹配时,需要显示实例化;

具体如下:

template <typename T>bool IsEqual (const T& left , const T& right ){return left == right;}void test1 (){cout<<IsEqual (1,1)<<endl;//cout<<IsEqual(1,1.2)<<endl; // 模板参数不匹配cout<<IsEqual<int>(1,1.2)<< endl; // 显⽰实例化cout<<IsEqual<double>(1,1.2)<< endl; // 显⽰实例化}

在test1()函数,注释的这句代码中有IsEqual(1,1.2),这就是模板参数不匹配,从而需要进行处理,修改为:IsEqual<int>(1,1.2);或修改成如下代码:

template <typename T1, typename T2>bool IsEqual (const T1& left , const T2& right){return left == right;}void test1 (){cout<<IsEqual(1,1)<<endl;cout<<IsEqual<int>(1,1)<< endl;cout<<IsEqual(1,1.2)<<endl;}
从而达到不同类型也可以进行比较。

2.模板类

模板类的格式:
template<class 形参名1, class 形参名2, ...class 形参名n>
class 类名
{ ... };

以实现动态顺序表为例:

template<typename T>class SeqList{public :SeqList();~ SeqList();private :int _size ;int _capacity ;T* _data ;};template <typename T>SeqList <T>:: SeqList(): _size(0), _capacity(10), _data(new T[ _capacity]){}template <typename T>SeqList <T>::~ SeqList(){delete [] _data ;}void test1 (){SeqList<int > sl1;SeqList<double > sl2;}
其中,SeqList为类名,SeqList<T>为类型名,这是使用模板类的不同之处。
同时,在运行时,编译器推演过程及模板类的实例化如下图所示:


当测试函数中创建两个不同的顺序表sl1,sl2,时,整型的顺序表sl1,传递参数后,编译器通过传递的参数进行推演,得到整型的顺序表结构,同理可得,双精度浮点型的顺序表sl2也通过编译器推演的到相应的结构。