我们可以建立template classes,使它们能够神奇地操作任何类型的资料。下面这个例子是让CThree 类别储存三个成员变量,成员函数Min 传回其中的最小值,成员函数Max 则传回其中的最大值。我们把它设计为template class,以便这个类别能适用于各式各样的数据类型:
template <class T>class CThree{public :CThree(T t1, T t2, T t3);T Min();T Max();private:T a, b, c;};
语法还不至于太稀奇古怪,把T 看成是大家熟悉的int 或float 也就是了。下面是成员函数的定义:
template <class T>T CThree<T>::Min(){T minab = a < b ? a : b;return minab < c ? minab : c;}template <class T>T CThree<T>::Max(){T maxab = a < b ? b : a;return maxab < c ? c : maxab;}template <class T>CThree<T>::CThree(T t1, T t2, T t3) : a(t1), b(t2), c(t3){return;}
这里就得多注意些了。每一个成员函数前都要加上template <class T>,而且类别名称应该使用CThree<T>。
//以下是template class 的使用方式:#include <iostream.h>void main(){CThree<int> obj1(2, 5, 4);cout << obj1.Min() << endl;cout << obj1.Max() << endl;CThree<float> obj2(8.52, -6.75, 4.54);cout << obj2.Min() << endl;cout << obj2.Max() << endl;CThree<long> obj3(646600L, 437847L, 364873L);cout << obj3.Min() << endl;cout << obj3.Max() << endl;}
执行结果如下:
2 5
-6.75
8.52
364873
646600
对程序员而言C++ templates 可说是十分容易设计与使用,但对于编译器和联结器而言却是一大挑战。编译器遇到一个template 时,不能够立刻为它产生机器码,它必须等待,直到template 被指定某种类型。从程序员的观点来看,这意味着template function 或template class 的完整定义将出现在template 被使用的每一个角落,否则,编译器就没有足够的信息可以帮助产生目的码。当多个源文件使用同一个template 时,事情更趋复杂。
随着编译器的不同,掌握这种复杂度的技术也不同。有一个常用的技术,Borland 称之为Smart,应该算是最容易的:每一个使用Template 的程序代码的目的档中都存在有template码,联结器负责复制和删除。
假设我们有一个程序,包含两个源文件A.CPP 和B.CPP,以及一个THREE.H(其内定义了一个template 类别,名为CThree)。A.CPP 和B.CPP 都包含THREE.H。如果A.CPP以int 和double 使用这个template 类别,编译器将在A.OBJ 中产生int 和double 两种版本的template 类别可执行码。如果B.CPP 以int 和float 使用这个template 类别,编译器将在B.OBJ 中产生int 和float 两种版本的template 类别可执行码。即使虽然A.OBJ 中已经有一个int 版了,编译器没有办法知道。然后,在联结过程中,所有重复的部份将被删除。