【一天一篇CPP】类模板

来源:互联网 发布:小米数据流量怎么改dns 编辑:程序博客网 时间:2024/05/19 23:16

1.什么是模板?先介绍和类对象无关的模板。

我们可以用

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

来代替宏,且刚好在这种情况下,两种写法刚好等效

#define min(a,b)    ( ( (a) < (b) )?  (a) : (b) ) 

但是模板不是宏,更像编译器内部的复制粘帖,为我们准备好我们需要的东西

上面的模板可以在编译器中扩展为char类型或其它int之类的类型【当我们使用了某种类型,编译器便生成一个对应版本】

const char min(const char& a, const char& b){return (a<b) ? a : b;}

这就是模板,但模板不止能“复制函数”,也能复制类的一些参数,例如我们今天学的 模板类。


如何使用模板?

template <class R, class T1, class T2>R add2 (const T1& s1, const T2& s2){return static_cast<R> (s1+s2);add<double> (1.1,2.2)add<int> (1.1,2.2)因为T1和T2被编译器识别了,所以不用写成add<double,double,double> (1.1,2.2)


2.有时对类而言,两个或多个类,其功能是相同的,仅仅是数据类型不同。

请看下面两个类:

class Compare_int{public:Compare_int( int a, int b){x = a; y = b;}int max(){return (x>y)? x : y;}int min(){return (x<y)? x : y;}private:int x, y;};class Compare_float{public:Compare_float( float a, float b){x = a; y = b;}float max(){return (x>y)? x : y;}float min(){return (x<y)? x : y;}private:float x, y;};

这时可用类模板【参数化的类】

类是对象的抽象,对象是类的实例。类模板是类的抽象,类是类模板的实例。

#include <iostream>using namespace std;template<class numtype>class Compare{public:Compare( numtype a, numtype b){x = a; y = b;}numtype max(){return (x>y)? x : y;}numtype min(){return (x<y)? x : y;}private:numtype x, y;};int main(){Compare<int> i(100,50);cout << i.max() <<endl;Compare<float> f(1.5,50.5);cout << f.max() <<endl;Compare<char> c('a','C');cout << c.max() <<endl;}

仅仅是修改了类名,增加了template<class numtype>,然后类里面的int 或 float 都用numtype 替代。

然后在main中,在定义Compare对象的时候,加上<int>制定具体类型。【这是唯一需要指定类型的地方】

用类模板定义对象时用以下形式:类模板名<实际类型名> 对象名;         或               类模板名<实际类型名> 对象名(实参列表);



3.类模板的成员函数在类外定义:

错误写法:numtype Compare::max(){.................}正确写法:template <class numtype>numtype Compare<numtype>::max()    {return (x > y)? x : y ; }

4.类模板的类型参数可以有一个或多个,每个类型前面都必须加上class【或typename,和class一般是等价的】
template <class T1, class T2>class A{.........};定义类对象的方法:A<int,double> a1;

5.模板可以有层次,一个类模板可以作为积累,派生出模板类。


6.模板类和模板类函数的特殊化【特殊化:就是当模板参数在某种具体类型的时候,才会调用】

如下面有四段小代码:

    其中第二段中的类定义是第一段中的模板类apImageTest的参数为unsigned char时候的特殊化。

    第四段中的类函数定义是第三段中模板类的成员函数在模板类的参数为unsigned char时候的特殊化,同时也和第二段的特殊化类定义想对应!

//定义模板类template<typename Pixel> class apImageTest{        //模板参数建议为大写public:apImageTest (int width, int height, Pixel* pixels);Pixel *getPixel (int x, int y);void setPixel (int x, int y, Pixel *pixel);private:    T *pixels_;    int width_, height_;};//特殊化定义模板类template<> class apImageTest<unsigned char>{public:    apImageTest (int width, int height, unsigned char *pixels);    unsigned char* getPixel (int x, int y);    void setPixel (int x, int y, unsigned char *pixel);private:    unsigned char *pixels_;    int width_, height_;    };//定义模板类函数template<class T>apImageTest<T>::apImageTest (int width, int height, T* pixels) :     width_(width), height_(height), pixels(0){    pixels_ = new T[width_ * height_];    T *p = pixels_;    for (int y = 0; y < height; y++)        for(int x = 0; x < width; x++)            *p++ = *pixels++;           //use assignment to copy pixels}//特殊化定义模板类函数apImageTest<unsigned char>::apImageTest    (int width, int height, unsigned char* pixels) :     width_ (width), height_ (height), pixels_ (0){    pixels_ = new unsigned char[width_ * height_];    memcpy (pixels_, pixels, width_ * height_);}





原创粉丝点击