C++程序是由函数和类组成的,座椅模板也分为类模板和函数模板。模板就是把功能相似、仅数据类型不同的函数或类设计为通用的函数模板或类模板,提供给用户。
模板是“泛型编程”的基础,所谓泛型编程就是用独立于任何特定类型的方式编写代码。所以简单地说,类是对象的抽象,而模板又是类的抽象,用模板能定义出具体类。
模板的语法:
函数模板的一般定义形式为:
Template<class或typename T>返回类型 函数名(函数形参表)
{
//函数定义体
}
模板定义以关键字template开始,后接模板形参表(template parameter list),模板形参表是用尖括号括住的一个或多个模板形参(template paramete)的列表。形参由关键字class或typename及其后面的表示符构成,形参之间以逗号进行隔开。
模板形参表不能为空。模板形参分为以下两种:
(1)模板类型参数,代表一种类型;
(2)模板非类型参数,代表一个常量表达式。
注:模板非类型参数的类型必须是:①整型或枚举;②指针类型(普通对象的指针、函数指针、成员指针);③引用类型(指向对象或者指向函数的引用)。
例:对前面的max()函数可以用模板定义如下:
template<typenameT>T Max(T a, T b)//比较两个任一类型的参数,返回较大者
{
returna > b ? a : b;
}
类模板与函数模板类似,使得一个类可以有基于通用类型的成员,而不需要在类生成的时候定义具体的数据类型。类模板的一般定义形式如下:
Template<classT>
Class类名
{
//类定义
};
其中,template是申明各模板的关键字,表示声明一个模板。模板参数可以是一个,也可以是多个,但应该是抽象化的结果,而不应该是具体的(例如int和float等)类型。如成员函数的参数或返回类型,且前面加上形参类型。
例:定义一个模板,用来存储两个任意类型的元素
template<classT>
class pair
{
Tvalue1, value2;
public:
pair(Tfirst, T second)
{
value1= first;
walue2=second;
}
};
函数模板
定义一个函数模板,比较两个相同数据类型的参数的大小
#include"iostream"
using namespace std;
template <classT> T Max(T x, T y)
{
returnx > y ? x : y;
}
void main()
{
intn1 = 5, n2 = 6;
doublen3 = 1.23, n4 = 2.356;
cout<< Max(n1, n2) << endl;
cout<< Max(n3, n4) << endl;
}
输出结果如下:
6
2.356
请按任意键继续. . .
类模板
与函数模板不同,函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化则必须是有程序员中显式的指定。实例化的一般形式是:
类名<数据类型数据,数据类型数据···>对象名
例:接收两个不同类型的变量并显示。
#include"iostream"
using namespace std;
template <classT1,class T2>
class myClass
{
private:
T1a;
T2b;
public:
myClass(T1x, T2 y)
{
a= x;
b= y;
}
voidshow()
{
cout<<"a="<< a << " "<<"b=" << b<< endl;
}
};
void main()
{
myClass<double,double>obj1(1.2,1.5);
obj1.show();
myClass<int,int>obj2(1, 5);
obj2.show();
}
输出结果如下:
a=1.2 b=1.5
a=1 b=5
请按任意键继续. . .
模板的编译模型
标准C++为编译模板代码定义了两种模型:包含编译模型和分离编译模型。在这两种模型中,构造程序的方式基本相同,类定义和函数声明都放在头文件中,而汗水定义和成员定义则放在源文件安装。不同之处在于编译器怎样使用来自原文件的定义。
包含编译模型
例:对函数模板中的例子进行改写
在头文件max.h中进行函数模板的声明,代码如下:
#ifndef MAX_H
#define MAX_H
template<typename Type> Type max(Type x, Type b);
#include"max.cpp"
#endif
对应的包含模板定义的源文件为max.cpp,代码如下:
template <classType>
Type max(Type x, Type y)
{
returnx > y ? x : y;
}
主源文件的代码如下:
#include"iostream"
#include"max.h"
using namespace std;
void main()
{
intn1 = 5, n2 = 6;
doublen3 = 1.23, n4 = 2.356;
cout<< max(n1, n2) << endl;
cout<< max(n3, n4) << endl;
}
输出结果如下:
6
2.356
请按任意键继续. . .
分离编译模型
分离编译模型中,编译器会为我们跟踪相关的模板定义,可以通过export关键字来实现。关键字export高速变一器在生成别其他文件使用的函数模板实例时,可能需要这个模板定义。编译器必须保证在生成这些实例时该模板定义是可见的。可以通过在模板定义中的关键字tempalte之前加上关键字export来声明一个可导出的函数模板。当函数模板被导出时,我们就可以子啊任意一个程序文本文件中使用模板的实例,而我们所需要做的就是在使用之前声明该模板。如果省略了模板定义中的关键字export,编译器就可能不能实例化函数模板的实例,也就不能正确链接程序。