1、第九章 模板,将对象类型参数化,使一段程序可以用于处理多种不同类型的对象,即实现了参数化多态性。模板是C+支持参数化的工具。C+的源程序由函数和类组成,模板也分为函数模板(Function Template)和类模板(Class Template) 9.1 函数模板 9.1.1 引入函数模板 9.1.2 函数模板的定义 9.2 类模板 9.2.1 类模板的定义 9.2.2 模板类的实例化和对象的定义 小结,9.1.1 引入函数模板,函数模板的有关概念如swap()函数,它的功能是对两个数据进行交换。 若数据都是整型,则该函数为: void swap(int ,若数据都为实型,则写成: void
2、 swap(float ,如果交换的是两个同一class类型A的对象,则有: void swap(A ,9.1.1 引入函数模板(续1),将交换函数swap()抽象成一个模板,将数据类型作为它的一个参数,就构成了函数模板,即template void swap(T /实例化为double型,也可用typename,例9.1 用函数模板把多个重载函数归纳为一个,/定义Point类,将其对象作为模板参数的实参 #include class Pointint x,y; public:Point(void) x=0; y=0; Point(int i,int j) x=i; y=j; int Read
3、X(void) return x; int ReadY(void) return y; void Move(int xOffset,int yOffset) x+= xOffset; y+= yOffset; friend ostream ,例9.1 用函数模板把多个重载函数归纳为一个(续1),template void swap(T ,9.1.1 引入函数模板(续2),函数模板实例化成模板函数,9.1.2 函数模板的定义,定义格式为:template 函数名(形式参数表) 1. 每个参数前面都用关键字class或typename来表示,标识符Tn可以是各种基本数据类型及用户定义的class类
4、型; 2函数模板是一个信息不完整而无法调用的函数样板。使用时必须实例化; 3作为模板实参的类,必须在定义该类时,自行编写有关的重载运算符函数。 4函数模板是虚拟的,所以定义格式中没有存储类的说明。 5重载模板函数。C+还允许函数模板被一个或多个同名的非模板函数所重载。,9.1.2 函数模板的定义(续1),例9.2 函数模板max的应用实例。 注意:此例在Point类中重载运算符” 为友元函数 /point.h #include class Point int x,y;public:Point(int i=0,int j=0) x=i; y=j;friend int operator(Point
5、 ,9.1.2 函数模板的定义(续2),#include #include using namespace std; #include “point.h“ template T ,(1)max(i,j) is 78 (2)max(x,y) is 72.9 (3)max(p1,p2) is P(128,64) (4)max(s1,s2) is China,string s1=“Beijing“,s2=“China“;,9.2.1 类模板的定义,类模板:C+允许用户为某个类定义模板,使得类中的某些数据成员、成员函数的参数、成员函数的返回值能取任意类型。,9.2.1 类模板的定义(续1),类模板定义
6、的一般格式: 声明部分: template class 类模板名 /类体,类定义的声明部分 ; 成员函数在类外实现部分: template 类模板名 :成员函数名1(形参表) /成员函数1的函数体 template 类模板名 :成员函数名n(形参表) /成员函数n的函数体,模板参数表,9.2.1 类模板的定义,1类模板是用于不同数据类型的一个类的样板,是一个信息不完整、无法使用的类。使用时,必须把模板参数实例化成一种特定的数据类型,实例化模板参数的参数称为模板实参。2.与类的成员函数类似,类模板的所有成员函数都必须在类体内用函数原型加以声明,而成员函数的定义既可以在类体外,也可以在类体内定义。
7、在类体外定义时,必须用”类模板名:”指明该成员函数所属的类模板,它也可以看成是类模板的类名。,9.2.1 类模板的定义(续),3.在每个类模板成员函数的实现部分开头,都需要有一个模板参数列表,即:template 表示这是一个类模板的成员函数。4.类模板是虚拟的,使用时必须实例化,实例化的一般格式为:模板名 对象名列表(初始值);当实例化为char型、int型、double型或用户定义的class类型时,类模板就实例成一个模板类。,9.2.2 类模板的实例化和对象的定义,9.2.2类模板的实例化和对象的定义(P288例9_2),/Store.h #include using namespace
8、 std; struct Student int id; /学号float gpa; /平均分 ; template class Store /实现对任意数据的存取 public:Store();/无参构造函数T GetItem();void PutElem(T x);private:T item; /用于存放任意类型的数据int haveValue;/标记item是否已被存入内容 ;,template Store:Store():haveValue(0) template T Store:GetItem() if (haveValue=0)cout void Store:PutElem(T
9、x) haveValue+;item=x; /将x值存入item,9.2.2类模板的实例化和对象的定义,/主程序 #include “Store.h“ void main() Student g=1000,23; /声明结构体变量g并进行初始化Store S1,S2; /声明两个Store类对象,其数据成员item为int型Store S3; Store D; S1.PutElem(3); /向S1中存入数据S2.PutElem(-7);coutS1.GetItem()“ “S2.GetItem()endl;S3.PutElem(g); /向S3中存入数据cout“The student id
10、 is “S3.GetItem().idendl;cout“Object D “;coutD.GetItem()endl; /D未经初始化,输出: 3 -7 The student id is 1000 Object D No item present!,9.2.2类模板的实例化和对象的定义,2类模板、实例化的模板类及其对象的关系,类模板 template class Store ;,模板类 类名Store : 存储类,对象S1,S2 Store S1,S2; 整数型,对象D Store D; 双精度实型,对象S3 Store s3; 结构体型,实例化,实例化,实例化,实例化,/Add.h #
11、include template class Add / public:Add();/无参构造函数T1 Print();void Put(T1,T2);private:T1 a; T2 b; ; template Add:Add():a(0),b(0) template T1 Add:Print() cout void Add:Put(T1 x,T2 y) a=x;b=y; ,/主程序 #include “Add.h” void main() Add S1;Add S2; S1.Put(3,5.3); S2.Put(5.3,3);coutS1.Print()endl;coutS2.Print()endl; ,运行结果: 3+5.3=8 5.3+3=8.3,小 结,1模板是一种高效率重用程序代码的方式,C+有函数模板和类模板,它们都是虚拟的,必须随模板参数的实例化而成为模板函数和模板类。每个模板类的实例是一个具体的对象,可以像普通对象一样使用,作为函数参数或返回值。 2函数模板和类模板的定义通常放在头文件中,便于所有的源文件引用。,