CPP-Templates

来源:互联网 发布:当前大数据发展趋势 编辑:程序博客网 时间:2024/04/29 20:59

如果我们要处理一批数据,则可以构造一个vector container. 假设数据是整数。随后我们需要类似的操作,但操作数是double。我们就要重新实现前面的container. 另外例子包括构造一个比较大小的函数,如果函数是整数,双精度,或者字符,我们需要分别实现。这显然是重复。

为了解决此类问题,c++推出了摸版类。类似概念还有函数摸版。
见下例子:

#include <iostream>using namespace std;template <class datatype>class Compare{public:    Compare(datatype a, datatype b)    {x=a;y=b;}    datatype max()    {return (x>y)?x:y;};    datatype min()    {return (x<y)?x:y;}private:    datatype x,y;};
#include "template1.h"int main( ){   Compare<int > cmp1(12,41);  //compare integer   Compare<double > cmp2(90.213,23.076);  //compare double   Compare<char> cmp3('n','x');  // compare char   return 0;}

template 定义了摸版。格式:

1 template<class 模板参数表>2 3 class 类名{4 5 // 类定义......6 7 };

其中,template 是声明类模板的关键字,表示声明一个模板,模板参数可以是一个,也可以是多个,可以是类型参数 ,也可以是非类型参数。类型参数由关键字class或typename及其后面的标识符构成。非类型参数由一个普通参数构成,代表模板定义中的一个常量。

template<class type,int width>2 3 //type为类型参数,width为非类型参数4 5 class Graphics;

再看类定义:

template <class T>class Matrix{public:...private:T *a;int r,c;};

template 暗示class Matrix是一个摸版,不是一个普通类。摸版参数在〈〉中暗示。此例子中,仅有一个摸版参数,名字是T. 但允许有多个。<>中的class暗示T是一个类型参数,意思是T被分配了一个类型,可以是任何类型,注意此处尽管用了class,但其实T也可以是普通类型,例如char, int等。在T被这样定义以后,它就可以在类的中间像普通类型名一样用来设置变量类型。

注意由于类是用摸版定义,因此类中的成员函数也需要改用摸版来定义。

上例中类摸版只有一个摸版参数。但其实一个类摸版或者函数摸版都可以有任意数目的摸版参数。摸版参数分为两类:类型参数(type parameters)和值参数(value parameters)。类型参数用关键字class或tupename*定义。 关键字typename是c++中后引入的,老版本编译器不支持,因此class是最常用的。值参数看起来象普通函数参数,但不能是浮点类型。(type parameters are preceded by the word class or typename* and designate arbitary types, Value parameters look like ordinary function parameters but may not be of floating point type).

例如我们可以定义一个stack摸版类,含两个参数,一个指定stack中单个元素的类型,另一个指定stack的尺寸。

template<class T, int size>class Stack{public:Stack():n(0){};bool empty(){return n<=0;}void push(const T& e){s[n++]=e;}void pop(){n--;}T top(){return s[n-1];}private:T s[size];int n;};

当我们实例化这个类摸版时候,我们要给两个摸版参数分别赋值。例如我们可以声明一个整数stack,尺寸200。

Stack<int,200> x; //a stack with maximum of 200 int

像普通函数,摸版参数也能有默认值。例如:

template<class T=double, int size=100>

如果一个摸版参数有默认值,那么所有后续的都要有默认值。当有默认值时,我们定义时不用指定所有参数,例如:

Stack<Person> y //a stack with a maximum of 100 persons (person is class)Stack<> z; //a stack with a maximum of 100 double.

最后,类并不是唯一可以被一般化的东西,函数也可以。看下面函数摸版例子:

int min(int a, int b){     if(a < b)    return a;    else     return bl;}

上述函数实现两个整数比较,推广到一般情况:

template<class T>const T & min(const T& a, const T& b){if(a<b)return a;elsereturn b;}

第一行首先暗示是个摸版,T是类型参数名字。接下来一行给出了函数定义。int 被T 代替。注意a,b被写成了常引用,因此避免了拷贝整个对象。

另外一个例子,找数组中最小元素:

template <class T>T & min_element(T f[], int n){int m=0;for(int i=1;i<n;i++)if(f[i] < f[m])m = i;return f[m];}
0 0
原创粉丝点击