函数模板与类模板

来源:互联网 发布:ubuntu telnet 命令 编辑:程序博客网 时间:2024/06/18 04:48

1、函数模板
函数模板是通用的函数描述,他们使用泛型来定义函数,其中泛型可用具体的类型(如int,double,char,string…)替换,通过将类型作为参数传递给模板,可使编译器生成该类型的函数。如果需要将同一个算法用于不同的类型的函数时,就使用模板。
(1)函数模板的一般形式:

template<typename 数据类型参数标识符><返回类型><函数名>(参数表){    函数体}

关键字template和typename是必须的,除非可以用关键字class替换typename。
如:

template<typename T>void swap(T & a,T & b){   T temp;   temp=a;   a=b;   b=temp;}

使用时:

int x,y;x=2;y=4;swap(x,y);//使用int实例化模板函数swapdouble a,b;a=9.999;b=11.111;swap(a,b);//使用double实例化模板函数swap

(2)重载函数模板
可以像重载常规函数定义那样重载模板的定义,而且并非所有的模板参数都必须是模板参数类型;
如:

template<typename T>void swap(T & a,T & b);template<typename T>void swap(T & a[],T & b[], int n);

(3)具体化
具体化分为:显式具体化,显式实例化,隐式实例化。
显式具体化:具体化函数定义,当编译器找到与函数调用匹配的具体化定义时,将使用该定义,而不再使用模板。

template <> void swap<job>(job &,job &);//显式具体化函数swap

对以下的三个swap函数:

void swap(job &, job &);//非模板函数void swap(T &,T &);     //模板函数template <> void swap<job>(job &,job &);//具体化函数

如果有多个函数原型,则编译器在选择原型时,优先级为:非模板函数>显示具体化函数>模板函数

隐式实例化:

int x=2;int y=4;swap(x,y);//使用int隐式实例化swap

显式实例化:

template void swap<double>(double &,double &);//显式具体化swap

2、类模板
容器类(如:Stock类,Queue类)被设计用来存储其他对象或者数据类型;
类模板提供参数化类型,即能够将类型名作为参数传递给接收方来建立类或函数。如,将int传递给Queue模板,可以让编译器构造一个对int进行排队的Queue类;将double传递给Queue模板,可以让编译器构造一个对double 进行排队的Queue类..
(1)模板类代码的开头:

template<class Type>

如声明Stock模板类:

template <class Type>class Stocke{private:   enum {MAX=10};   Type items[MAX];   int top;public:  Stock();  bool isempty();  bool isfull();  bool push(const Type & item);  bool pop(Type & item);};模板类成员函数的定义必须也在同一个.h文件中给出,不能放在相应的.cpp中;template <class Type>Stock<Type>::Stock(){top=0;}template <class Type>Stock<Type>::isempty(){return top==0;}....

使用模板类时,需要声明一个类型为模板类的对象,使用所需的具体类型替换泛型名。
如对于上面的Stock模板类:

Stock<int>  kernels;  //使用double实例化类模板,infos是double的stockStock<double> infos;  //使用double实例化类模板,infos是double的stock

(2)数组模板和非类型参数

template <class T,int n>class ArrayTP{ private:   T ar[n]; public:   ArrayTP(){}   explicit ArrayTP(const T & v);   virtual T & operator[](int i);   virtual T operator[](int i) const;};

定义函数时:

template<class T,int n>ArrayTP<T,n>::ArrayTP(const T & v){   for(int i=0;i<n;i++)      ar[i]=v;}......

使用:

ArrayTP<double, 12> egg;//T=double , n=12

递归使用函数模板;

ArrayTP<ArrayTP<int,5>,20> dd;

使用多个类型参数:

template<class T1,class T2>class Pair{private:   T1 a;   T2 b;public:   T1 & first();   T2 & second();};template <class T1,class T2>T1 & Pair<T1,T2>::first(){return a;}.....

应用:

Pair<string,int> one("we are...",12);
原创粉丝点击