函数模板
函数模板可以用来创建一个通用的函数,以支持多种不同的形参,避免重载函数的函数体重复设计。它的最大特点是把函数使用的数据类型作为参数。
函数模板提供一个种用来自动生成各种类型函数实例的算法,程序员对于函数接口参数和返回类型中的全部或者部分类型进行参数化(parameterize)而函数体保持不变。
下面是min()的函数模板定义:
template<typename Type>
Type min(Type a,Type b){
return a < b ? a : b;
}
#include<iostream>
using namespace std;
template<typename T> //template<class T>
T n_add(T a,T b){
T c;
c=a+b;
return c;
}
int main(){
cout<<n_add(5,3)<<endl;
cout<<n_add(5.35,5.5)<<endl;
system("pause");
}
函数模板的重点是模板。表示的是一个模板,专门用来生产函数。
模板函数的重点是函数。表示的是由一个模板生成而来的函数。
类模板
类模板是一种对类型进行参数化和实现代码复用的技术。使用类模板可以提高数据的处理效率。
例如:设计一个栈的类。如果不采用类模板,则在设计之初就要确定栈中数据的类型。如果采用类模板,则只需通过类模板实例化实现。
使用类模板的主要优点:
类模板是C++语言的一个非常重要的特征,在C++的标准模板库(Standard Template Library,简称STL)中提供了大量的类模板,有关STL的内容将在后面章节中详细讲述。
类模板的一般定义:
类模板定义最后的分号不可省,因为与类的定义一样,类模板的定义也是一条语句,需要一个分号作为语句的结束。
定义类模板的成员函数时,有两种方法如图所示:
在类的外部定义类模板的成员函数的一般形式:
使用模板参数
在定义类模板的数据成员和函数成员时,可以使用模板参数:
类模板可以使用非类型参数。非类型的参数通常在模板定义过程中当做常量使用。例如上例中的类模板Array的第二个模板参数size即是一个非类型的参数,并且该参数用来设定数组的长度。
使用非类型参数
声明一个类模板的非类型参数的一般语法形式如:
对于带有非类型参数的类模板,实例化时需要用一个常量来指定这个参数:
模板参数的默认实参
定义类模板时,可以设定其参数的默认值,即参数的默认实参,包括默认类型参数和默认非类型参数。例如,对于Array模板,设定其默认保存的数据类型为int型,并且其数组尺寸的默认值为100:
生成模板实例
类模板只是一个模板,不是实际的类。使用类模板时必须先实例化,即给类模板参数赋值。
实例化类模板时,对于类型参数,可以用C++内建的类型实例化,也可以用自定义的类型。类模板在实例化时没有参数推导机制,所有的模板参数必须指定,除非模板参数带有默认实参。例如,实例化类模板Array:
非类型参数的模板实例化:
类模板示例
在实际开发中,类模板经常用做一个可以处理各种类型数据的容器。比如一个先入后出的栈,如果将栈定义成一个类模板,则可以用来处理各种数据,方便使用。
下面程序定义一个Stack类模板,其模板参数有类型参数和非类型参数,并用这个类模板来处理不同类型的数据,实现代码及结果:
代码中声明一个类模板Stack,成员函数push()和pop()分别用来向类中添加元素和弹出元素。在main()函数对类模板Stack进行实例化并创建对象,然后调用成员函数进行栈的相关操作。