教学目标
●用函数模板生成相关(重载)函数组
●区分函数模板与模板函数
●用类模板生成相关类型组
●区分类楼板与模板类
●了解如何重载模板函数
●了解模板、友元、继承与静态成员之间的关系
本章介绍C++最强大的特性之一 —— 模板。模板使我们可以用一个代码段指定一组相关(重载)函数(称为模板函数)或一组相关类(称为模板类)。
我们可以对数组排序函数编写一个函数模板,然后Cc++自动生成模板函数,可以对int数组、float数组和字符串数组等等进行排序。
第3章介绍了函数模板。如果读者没有阅读该章,则这里再提供一些介绍和例子。
我们可以对堆栈类编写一个类模板,然后让C++自动生成如int、float和string堆栈类的类模板。
注意区分函数摸板与模板函数:函数模板和类模板像是具有各种形状的模板,而模板函数和模板类则相当于按照模板描绘,其形状都是相同的.只是画上不同的颜色。
模板是C++的软件复用的功能之一。
本章介绍一些函数模板和类模板的例子,并介绍模扳与其他C++特性(如重载、继承、友元和static成员)之间的关系。
这里介绍的模扳机制的设计和细节基于Bjarne Stroustrup的论文《Parameterized Types for C++》,发表于1988年10月在科罗拉多州丹佛举办的USENIX C++会议上(Proceedings of the USENIX C++ Conference)。
本章只是关于模板问题的简介,第20章“标准模板库(STL)”将深入介绍模板容器类、迭代器和STL算法。第20章有几十个基于摸板的“有生命力的代码”,演示了更复杂的模板编程技术。
重载函数通常是基于不同的数据类型完成类似的操作。如果对每种数据类型的操作是相同的,那么用函数模扳完成这项工作更为简洁和方便。程序员对函数模板的定义只编写一次。基于调用函数时提供的参数类型,C++自动产生单独的目标代码函数来正确地处理每种类型的调用。在C浯言中,这个任务是用预处理指令#define建立的宏完成的(见第17章)。但是,宏可能会产生副作用,并且使编译器不能进行类型检查。函数模板和宏一样的简洁,并且还能让编译器进行全面的类型检查。
函数模板和宏一样允许软件复用。但与宏不同的是,函数模板还可以消除许多类型错误,因为C++提供了安全的全面类型检查。
所有的函数模板定义都是用关键字template开始的,该关键字之后是用尖括号<>括起来的形式参数表。每一个形式参数之前都有关健字class,例如:
template或 template 或 template
内部类型和自定义类型可用来指定传递给函数的参数类型、函数返回类型和声明函数中变量,函数模板中的形式参数的用法与之类似。该函数定义的方式与定义其他函数类似。注意关键字class指定函数模板类型参数,实际上表示“任何内部类型或用户自定义类型”。
函数模板的每个形式类型参数之前不放置关键字class(或新的关键字typename)。
下面看看图12.1的printArray函数模板,这个函数的用法见图12.2的完整程序。
void printArray( const int*, const int );
void printArray( const double*, const int );
void printArray( const char*, const int );
// Fig 12.2: fig12_02.cpp
// Using template functions
#include <iostream.h>
template< class T >
void printArray( const T *array, const int count )
{
for (int i = 0; i < count; i++ )
cout << array[ i ] <<" ";
cout << endl;
}
int main()
{
const int aCount = 5, bCount = 7, cCount = 6;
int a[ aCount ] = { 1, 2, 3, 4, 5 };
double b[ bCount ] = { 1.1, 2.2, 3.3, 4.4, 6.5, 6.6, 7.7 };
char c[ cCount ] = "HELLO"; // 6th position for null
cout << "Array a contains:" << endl;
printArray( a, aCount ); // integer template function
cout << "Array b contains:" << endl;
printArray( b, bCount ); // double template function
cout << "Array c contains:" << endl;
printArray( c, cCount ); // character template function
return 0;
}
输出结果:
Array a contains:
1 2 3 4 5
Array b contains:
1.1 2.2 3.3 4.4 5.5 6.6 7.7
Array c contains:
H E L L O
图 12.2 使用模板函数
模板提供了软件复用的好处。请记住,尽管模板只编写一次,但程序中仍然实例化多个模板类的副本。这些副本会占用大量内存。