【一天一篇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_);}
- 【一天一篇CPP】类模板
- 【一天一篇CPP】友元和类
- 【一天一篇CPP】静态成员
- 【一天一篇CPP】C++的虚基类
- 【一天一篇CPP】inline、类的存储,简单的构造函数、析构函数
- 【一天一篇CPP】派生类的构造函数和析构函数
- 【一天一篇CPP】重载运算符的实例
- 【一天一篇CPP】多态性和虚函数和虚析构函数和纯虚函数和抽象类
- 【一天一篇CPP】运算符重载--对部分CPP运算符重载
- 杜教模板(转载一篇cpp文件)
- 【一天一篇CPP】基类与派生类的转换(单向:从派生类赋值给基类,舍弃一部分)
- 【一天一篇CPP】对象与指针与数组 对象和const和指针和引用
- 【一天一篇CPP】对象的动态建立、释放、赋值和赋值
- 【一天一篇CPP】不同类型数据间的转换【转换构造函数、类型转换函数】
- 【一天一篇CPP】继承和派生:基础知识和继承方式与访问属性
- 【一天一篇CPP】多继承及其二义性(multiple inheritance,也叫多重继承,但不是多层继承)
- 一天写一篇文章
- 第一天第一篇
- oracle字符集转换工具DMU使用
- 求两个字符串的最大公共子串
- 外部DTD文档
- FlexComboBoxTree
- jQuery+Ajax+Servlet进行验证码校验
- 【一天一篇CPP】类模板
- 今天面试的总结--百度
- remove1
- 解析“extern”
- remove1
- 线程的2种基本用法
- Cocos2d-x win7 + vs2010 配置图文详解(2012亦如此)
- 关于一个很好用的数据恢复软件的使用方法
- 如何将HACMP环境下的mount点路径变更为其他的目录