模板把函数或类要处理的数据类型参数化,表现为参数的多态性,称为类属。模板用于表达逻辑结构相同,但具体数据元素类型不同的数据对象的通用行为。
什么是模板
- 类属——类型参数化,又称参数模板
使得程序(算法)可以从逻辑功能上抽象,把被处理的对象(数据)类型作为参数传递 - C++提供两种模板机制:
- 函数模板
- 类模板
函数模板
考虑求两参数之中大值函数:
对 a, b 的不同类型,都有相同的处理形式:
用已有方法解决对不同数据类型处理:
- 宏替换
问题:避开类型检查
2. 重载
问题:需要许多重载版本
3. 使用函数模板
重载函数通常基于不同的数据类型实现类似的操作
对不同数据类型的操作完全相同,用函数模板实现更为简洁方便
模板说明
声明模板中使用的类属参数。形式为(template和typename都是关键字)
类型形式参数的形式为:
或
e.g.
函数模板与模板函数
函数模板声明
- 函数模板定义由模板说明和函数定义组成
- 模板说明的类属参数必须在函数定义中至少出现一次
- 函数参数表中可以使用类属类型参数,也可以使用一般类型参数
e.g.
输出结果为:
max (3, 5) is 5
max (‘y’, ‘e’) is y
max (9.3, 0.5) is 9.3
请按任意键继续. . .
重载函数模板
有些特殊情况需要函数模板参与重载
e.g.
当存在以下调用时候:
这种时候就需要进行重载
e.g.
输出结果为:
Max(3, ‘a’) is 97
Max(9.3, 0.5) is 9.3
Max(9, 5, 23) is 23
请按任意键继续. . .
匹配约定:
- 寻找和使用最符合函数名和参数类型的函数,若找到则调用它
- 否则,寻找一个函数模板,将其实例化产生一个匹配的模板函数,若找到则调用它
- 否则,寻找可以通过类型转换进行参数匹配的重载函数,若找到则调用它
- 如果按以上步骤均未能找到匹配函数,则调用错误
- 如果调用有多于一个的匹配选择,则调用匹配出现二义性
e.g.
类模板
- 类模板用于实现类所需数据的类型参数化
- 类模板在表示如数组、表、图等数据结构显得特别重要,这些数据结构的表示和算法不受所包含的元素类型的影响
类模板与模板类
类模板由模板说明和类说明构成
e.g.
数组类模板例子:
输出结果:
Integer Array :
0 1 2 3 4
Double Array :
0.35 0.7 1.05 1.4 1.75
请按任意键继续. . .
类模板作函数参数
- 函数的形式参数类型可以是类模板或类模板的引用对应的实际参数是该类模板实例化的模板类对象
- 当一个函数拥有类模板参数时,这个函数必定是函数模板
一个用 Array 作参数的函数模板:
调用函数模板
① 建立对象
调用构造函数,实例化模板类,建立对象
② 调用函数
在类层次中的类模板
一个类模板在类层次结构中既可以是基类也可以是派生类:
- 类模板可以从模板类派生
- 类模板可以从非模板类派生
- 模板类可以从类模板派生
- 非模板类可以从类模板派生
e.g.(从类模板Array派生一个安全数组类模板BoundArray
)
- 类模板派生普通类,在定义派生类时要对基类的抽象类参数实例化
- 从普通类派生模板类,意味着派生类添加了抽象类数据成员
从类模板A派生普通类B:
输出结果:
123
789
5.16
请按任意键继续. . .
类模板与友员
在类模板中可以声明各种友员关系
- 一个函数或函数模板可以类是或类模板的友员
- 一个类或类模板可以是类或类模板的友员类
- 声明这种模板之间的友员关系符号比较烦琐
函数f1成为类模板X实例化的每个模板类的友员函数
对特定类型(如double),使模板函数f2(X&)成为X的友员
A类的成员函数f3成为类模板X实例化的每个模板类的友员函数
对特定类型(如double),使模板类B的成员函数f4(X&)成为模板类X的友员
Y类的每个成员函数成为类模板X实例化的每个模板类的友员函数
对特定类型(如double),使模板类Z所有成员函数成为模板类X的友员
e.g.(为复数类模板用定义重载运算符友员函数)
输出结果为:
(-1.7 , -2.8)
(8.4 , 13)
(-2.5 , -3.7)
请按任意键继续. . .
在这里过于模板的操作符重载,在开始的时候有一个问题,参考文章如下:
关于操作符的友元模版函数重载
类模板与static成员
- 从类模板实例化的每个模板类有自己的类模板数据成员,该模板类的所有对象共享一个static数据成员
- 和非模板类的static数据成员一样,模板类的static数据成员也应该在文件范围定义和初始化
- 每个模板类有自己的类模板的static数据成员副本
e.g.(为圆类模板定义静态成员)
输出结果:
A.Radius = 16
A.Girth = 100.531
A.Area = 804.247
B.radius = 105
B.Girth=659.734
B.Area = 34636
Total1=2X.Radius = 6.23
X.Girth = 39.1442
X.Area = 121.934
Y.radius = 10.5
Y.Girth=65.9734
Y.Area = 346.36
Z.Girth=160.849
Z.Area = 2058.87
Total2=3
请按任意键继续. . .
关于模板补充
模板调用的两种方式