C++程序语言设计 Chapter 14: Templates
Outline 函数模板 类模板 标准模板库STL
回顾vector vector是一个模板(template),可以有效的用于不同的类型。 vector<string> v; ifstream in("FillVector.cpp"); string line; while (getline(in, line)) { v.push_back(line); } vector<int> v; for (int i = 0; i < 10; i ++) { v.push_back(i); }
模板(template) 将类型作为参数传给模板,由编译器生成该类型的函数或者类。 通用编程:模板允许以通用类型(而不是具体类型)的方式编写程序。 参数化类型:类型采用参数表示。
函数模板 编写一个交换两个int值的函数 再编写一个交换两个double值的函数 再编写一个交换两个char值的函数 void swap (int & a, int & b) { int temp; temp = a; a = b; b = temp; } 再编写一个交换两个double值的函数 再编写一个交换两个char值的函数
解决方案一 复制原来的代码,并分别用double和char替换所有的int 优点: 缺点: 思路简单明了 浪费时间,容易出错 如果修改算法,都需要修改
解决方案二 利用函数模板自动完成,只需指明其类型参数即可。 关键字class在较新的编译器中可以用typename替换。 template <class T> void swap (T & a, T & b){ T temp; temp = a; a = b; b = temp; } 关键字class在较新的编译器中可以用typename替换。 参看代码:funtemp.cpp
注意事项 模板与宏类似,由预处理域移至编译域。 模板并不处理函数,只是告诉编译器如何定义函数。 关键字typename更为明显的说明参数T表示类型,但大量的代码库还是使用class。 函数模板不能缩短可执行程序,最终的代码不包含任何模板,只包含实际生成的函数。 好处在于使生成多个函数定义简单、可靠。
函数模板重载 可以像重载常规函数定义那样重载函数模板定义。 被重载的函数模板的函数特征必须不同。 并非所有的函数模板参数都必须是函数模板参数类型。 参看代码:twotemps.cpp
显示具体化 假设有如下结构: 若只交换salary和floor成员,怎么办? 提供一个具体化函数定义,称为显式具体化 struct job { char name[40]; double salary; int floor; } 若只交换salary和floor成员,怎么办? 提供一个具体化函数定义,称为显式具体化 template <> void Swap<job>(job &, job &);
显示具体化 非模板函数 模板函数 显式具体化模板函数 void Swap (job &, job &); 模板函数 template <class T> void Swap (T &, T &); 显式具体化模板函数 template <>void Swap<job> (job &, job &); 非模板函数优先于显式具体化模板函数和模板函数,而显式具体化模板函数优先于模板函数。参考代码:twoswap.cpp
类模板 继承和组合并不是总能够满足重用代码的需要,还要用到类模板。 比如容器类,算法代码相同,只有保存的对象类型不同。 可以编写一个通用的容器类,将具体的类型作为参数传递给它。
类模板语法 采用template<class T>进行声明 template<class T> class Array{ enum { size = 100 }; T A[size]; public: T& operator[](int index) { return A[index]; } }; int main(){ Array<int> ia; Array<float> fa;}
非内联函数定义 需要在成员函数定义前看到template声明 在引用模板类名的地方,必须伴有该模板的参数列表 参看代码:Array.cpp
头文件 通常,即使是在创建非内联函数定义时,都把类模板的所有声明和定义放入一个头文件中。 不同的编译器实现方式不同,大多数允许在一个独特的cpp文件中放置类模板的定义,需要采用新的export关键字,且每个定义都要一export开始。
使用类模板 仅在程序中包含类模板并不能生成模板类,需要请求实例化。 与常规的函数模板不同,实例化类模板必须显式的提供所需的类型。 vector<string> v; vector<int> v; 与常规的函数模板不同,实例化类模板必须显式的提供所需的类型。 Swap (3, 4); Swap (0.4, 3.2);
标准模板库STL 阅读文档 C++ STL轻松导学.doc 来源: http://morningspace.51.net/index.php
下次课内容 异常处理、XML解析 谢谢大家!