【C++】模板简述(三):类模板
上文简述了C++模板中的函数模板的格式、实例、形参、重载、特化及参数推演,本文主要介绍类模板.
一、类模板格式
类模板也是C++中模板的一种,其格式如下:
template<class 形参名1, class 形参名2, ...class 形参名n> class 类名{ ... };
例如:我个人模拟实现的Vector的声明
template<typename T> class Vector{ public: typedef T* Iterator; //迭代器 typedef const T* ConstIterator; //const类型迭代器 public: //类的成员函数 Vector(); //构造函数 Vector(const Vector&); //拷贝构造 Vector& operator=(const Vector&); //赋值运算符重载 ~Vector(); //析构函数 public: //公共接口 void PushBack(const T &); //尾插 void PopBack(); //尾删 Iterator Find(const T &); //查找 void Insert(Iterator*); //插入 void Erase(Iterator*); //删除 void Size(); //获取有效元素个数 bool Empty(); //判断是否为空 void clear(); //清空 public: //迭代器接口 Iterator Begin(); //迭代器起始位置 Iterator End(); //迭代器结束位置 private: T *_start; T *_finish; T *_endOfStroage; };
二、模板类的实例化
只要有不同的类型,编译器就会实例化出一个对应的类,这点与函数模板非常相似.例如:
Vector<int> v1; Vector<char> v2;
当定义上述两个类型的Vector时,编译器会用int和char分别代替模板形参,重新编写Vector类,最后创建Vector<int>和Vector<char>类.
三、非类型的模板参数
对于函数模板和类模板,模板参数并不局限于类型,普通值也可以作为模板参数。例如:
template<typename T,int SIZE=10> class Array{ private: T _arr[SIZE]; };
虽然非类型模板参数很好用,但是也有一些限制:
注意:浮点数和类对象是不允许作为非类型模板参数的.
***函数模板不支持形参带默认值.
四、类模板的特化
模板的特话分为两种,全特化和偏特化.
全特化是指,所有的模板参数都要进行特化.例如:
template<typename T> class Vector{ public: Vector(); ~Vector(); private: T *_start; T *_finish; T *_endOfStroage; }; template<> class Vector<int>{ public: Vector(); ~Vector(); private: int *_start; int *_finish; int *_endOfStroage; } //不需要模板参数 Vector<int>::Vector(){ //代码 }
从上述代码我们可以看出:特化后定义成员函数不需要加模板参数.
偏特化,是指多个模板参数可以只特化一个或一部分.如:
template<typename T1,typename T2> class Add{ public: Add(); ~Add(); private: T1 _left; T2 _right; }; //只特化第一个参数 template<typename T2> class Add<int,T2>{ public: Add(); ~Add(); private: int _left; T2 _right; }; //特化指针类型 template<typename T1,typename T2> class Add<T1*,T2*>{ public: Add(); ~Add(); private: T1 _left; T2 _right; T1* _leftPtr; T2* _rightPtr; };
我们从上述代码可以看出,偏特化具有这样的特性:
偏特化并不仅仅局限于特化部分参数,而是对模板参数更进一步的条件限制所设定出来的一个特化版本.
最后的说明:
特化并不只是类模板才具有的特性,函数模板也具有特化功能,函数模板的特化与类模板类似.