templatetypename T T minT a T b return
模板函数举例 template<typename T> T min(T &a, T &b) { return a<b? a: b; } void main () { int i=2, j=3, c; c=min(i, j); cout<<‘‘c=’’<<c<<endl; }
我们先来看一个例子 #include “iostream. h” template<class T> //声明一个函数模板 T max(T x, T y) { return (x>y)? x: y; }
void main() { int a = 6, b = 8; float c = 8. 5, d = 2. 2; double e = 21. 123, f = 145. 987; char g = ‘z’, h = ‘m’; cout<<max(a, b)<<endl; //函数模板的实例化 cout<<max(c, d)<<endl; cout<<max(e, f)<<endl; cout<<max(g, h)<<endl; }
【程序 11. 1】 // 求两个int值的最小值 inline int const& min (int const& a, int const& b) { return a < b ? a : b; } // 求两个任意类型值的最小值 template <typename T> inline T const& min (T const& a, T const& b) { return a < b ? a : b; }
11. 3 模板类 11. 3. 1模板类的创建及使用 template <class Type> class Class. Name { //具体内容 }; 或 template <typename Type> class Class. Name { //具体内容 };
看下面一个例子: #include<iostream. h> template<class T 1, class T 2> //定义两个模板参数的类模板 class myclass{ T 1 i; T 2 j; public: myclass(T 1 a, T 2 b) { i=a; j=b; } void show() { cout<<”i=”<<i<<” j=“<<j<<endl; } }; //定义结束
//主程序 main() { myclass<int , double> ob 1(12, 0. 15); //定义模板类myclass<int, double> myclass<char, char*>ob 2(‘x’, “This is a test”); //定义模板类myclass<char, char*> ob 1. show(); ob 2. show(); return 0; }
class Text. File : public File { public: void Open(); void Save. As(String&); void Close(); }; class Image. File : public File { public: void Close(); void Save. As(String&); void Close(); };
// 通过菜单项打开文件 void menu_open_file(File* f_ptr) { f_ptr->Open(); . . . . } 可以如下运用上述代码: File *file_ptr = new Text. File(); menu_open_file(file_ptr); // 打开文本文件. . . . file_ptr = new Image. File(); menu_open_file(file_ptr); // 打开图片文件
11. 4高级编程 n 11. 4. 1动多态设计(Dynamic Polymorphism)
//poly/dynahier. h #include "coord. h" // 针对几何对象而设计的共通抽象基础类别 //(common abstract base class)Geo. Obj class Geo. Obj { public: // 绘制几何对象: virtual void draw() const = 0; // 传回几何对象的重心(center of gravity): virtual Coord center_of_gravity() const = 0; //. . . }; // 具象几何类别(concrete geometric class)Circle // 衍生自 Geo. Obj
class Circle : public Geo. Obj { public: virtual void draw() const; virtual Coord center_of_gravity() const; //. . . }; // 具象几何类别 Line // 衍生自 Geo. Obj class Line : public Geo. Obj { public: virtual void draw() const; virtual Coord center_of_gravity() const; //. . . }; //. . .
以本例而言,具体程序代码大致描绘如下: //poly/dynapoly. cpp #include "dynahier. h" #include <vector> // 绘制任何 Geo. Obj void my. Draw (Geo. Obj const& obj) { obj. draw(); // 根据对象的类型调用 draw() } // 处理两个 Geo. Objs 重心之间的距离 Coord distance (Geo. Obj const& x 1, Geo. Obj const& x 2) { Coord c = x 1. center_of_gravity() - x 2. center_of_gravity(); return c. abs(); // 传回坐标绝对值 }
// 绘出 Geo. Objs 异质群集(heterogeneous collection) void draw. Elems (std: : vector<Geo. Obj*> const& elems) { for (unsigned i=0; i<elems. size(); ++i) elems[i]->draw(); // 根据对象的类型调用 draw() } int main() { Line l; Circle c, c 1, c 2; my. Draw(l); // my. Draw(Geo. Obj&) => Line: : draw() my. Draw(c); // my. Draw(Geo. Obj&) => Circle: : draw() distance(c 1, c 2); // distance(Geo. Obj&, Geo. Obj&) distance(l, c); // distance(Geo. Obj&, Geo. Obj&) std: : vector<Geo. Obj*> coll; // 异质群集(heterogeneous //collection ) coll. push_back(&l); // 插入一个 line coll. push_back(&c); // 插入一个 circle draw. Elems(coll); // 绘出不同种类的 return 0; }
前一节中的函数 my. Draw ( ): void my. Draw (Geo. Obj const& obj) //Geo. Obj 是抽象 // 基础类别(abstract base class) { obj. draw( ); } 可设想改写如下: template <typename Geo. Obj> void my. Draw (Geo. Obj const& obj) //Geo. Obj 是模 板参数(template parameter) { obj. draw( ); }
现在使用静态多型机制改写前一节的例子。首先不再使用几何类别阶层 体系,而是编写若干个独立的几何类别: //poly/statichier. h #include "coord. h" // 具象的几何类别 Circle // 不衍生自任何类别 class Circle { public: void draw() const; Coord center_of_gravity() const; }; // 具象的几何类别 Line // - 不衍生自任何类别 class Line { public: void draw() const; Coord center_of_gravity() const; };
现在,这些 classes 的应用程序看起来像这样: //poly/staticpoly. cpp #include "statichier. h" #include <vector> // 绘出任何给定的 Geo. Obj template <typename Geo. Obj> void my. Draw (Geo. Obj const& obj) { obj. draw(); // 根据对象的类型调用 draw() } // 处理两个 Geo. Objs 重心之间的距离 template <typename Geo. Obj 1, typename Geo. Obj 2> Coord distance (Geo. Obj 1 const& x 1, Geo. Obj 2 const& x 2) { Coord c = x 1. center_of_gravity() x 2. center_of_gravity(); return c. abs(); // 传回坐标绝对值
// 绘出 Geo. Objs 同质群集(homogeneous collection) template <typename Geo. Obj> void draw. Elems (std: : vector<Geo. Obj> const& elems) { for (unsigned i=0; i<elems. size(); ++i) { elems[i]. draw(); // 根据元素的类型调用 draw() } } int main() { Line l; Circle c, c 1, c 2; my. Draw(l); // my. Draw<Line>(Geo. Obj&) => Line: : draw() my. Draw(c); // my. Draw<Circle>(Geo. Obj&) => Circle: : draw() distance(c 1, c 2); // distance<Circle, Circle>(Geo. Obj 1&, Geo. Obj 2&) distance(l, c); // distance<Line, Circle>(Geo. Obj 1&, Geo. Obj 2&) // std: : vector<Geo. Obj*> coll; // ERROR: 不可以是异质群集 std: : vector<Line> coll; // OK: 同质群集没问题 coll. push_back(l); // 安插一条直线 draw. Elems(coll); // 画出所有直线 return 0; }
n 每个线性容器不再需要提供诸如 max_element()这样的操作。容器只 需提供迭代器类型(iterators type)用以巡访(遍历)容器所含的 实值序列(sequence of values),并提供成员函数建立这样 的迭 代器即可: namespace std { template <class T, . . . > class vector { public: typedef. . . const_iterator; //与实作相依(implementationspecific). . . // 的iterator 类型,用于const vectors const_iterator begin() const; //传回一个 iterator, //指向群集头部 const_iterator end() const; //传回一个 iterator,指向群集 //尾端. . . };
template <class T, . . . > class list { public: typedef. . . const_iterator; //与实作相依 // (implementationspecific). . . // 的 iterator 类型,用于 const lists const_iterator begin() const; //传回一个 iterator, //指向群集头部 const_iterator end() const; //传回一个 iterator, //指向群集尾端. . .
n 现在,只要以群集起点和终点元素为自变量,调用泛化后的 max_element(),就可以找出任何群集的最大值(这里暂时省略对空 群集的特别处理): //poly/printmax. cpp #include <vector> #include <list> #include <algorithm> #include <iostream> #include "My. Class. h" template <typename T> void print_max (T const& coll) { // 声明群集的区域迭代器(local iterator) typename T: : const_iterator pos; // 计算最大值的位置 pos = std: : max_element(coll. begin(), coll. end()); // 打印出 coll 的最大元素(如果有的话):
if (pos != coll. end()) { std: : cout << *pos << std: : endl; } else { std: : cout << "empty" << std: : endl; } } int main() { std: : vector<My. Class> c 1; std: : list<My. Class> c 2; //. . . print_max (c 1); print_max (c 2); return 0; }
- Slides: 39