C++模板(下)

xiaoxiao2021-02-28  131

模板类

<1>模板类的格式

template <class T1,class T2,...> class//类名 { };

我们之前实现过顺序表,链表,为了方便以后通用,我们会定义一个新的 datatyppe 类型的来代替 int,以后要改变类型的话,就直接在声明中改变就好,学了模板后,我们就可以使用更方便的方法,就是用模板实现顺序表,链表,使代码的复用率大大提高。

template <class T> class Vector { private: T * _data;// 这里就直接用T int _siza; int _cappacity; }; //动态实现顺序表 template <class T> class Vector { private: T * _data; int _siae; int _capacity; public: Vector() :_siae(0) ,_cappacity(0) ,_data(new T[_cappacity])// 实现动态增容 {} };

如果给你一个数组arr,我想让它可以变化大小,我们应该怎么实现呢?这里又提到了非类型的模板参数,只是这个是用非类型的类模板参数实现的。

template <class T,size_t N = 5>//带缺省值的模板参数 class Arr { protected: T _a[N]; public: Arr(){} }; int main () { Arr <int ,10> a1; Arr <int> a2; Arr <char,10> a3; return 0; //这样就可以实现改变数组的大小。 }

<2>类模板的特化

模板特化不同于模板的实例化,模板参数在某种特定类型下的具体实现称为模板的特化。模板特化有时也称之为模板的具体化,分别有函数模板特化和类模板特化。 特化又可以分为:偏特化,全特化。

类模板的全特化

“` //下面这个是未特化的版本 template class Vector { public: Vector(int capacity) :_size(0) ,_capacity(capacity) ,_data(new T[_capacity]) {} ~Vector() { delete[]_data; } private: int _size; int _capacity; T * _data;

}; //注意特化之前必须先写这个未特化的版本,否则将会报错。如下图所示 //下面这个就是特化后的版本 template<> class Vector { public: Vector(int capacity) :_size(0) ,_capacity(capacity) ,_data(new int[_capacity]) {} ~Vector() { delete[]_data; } private: int _size; int _capacity; int * _data;

};

void test1() { Vector s1(2);//编译一下,你会发现它调用的就是已经特化的版本 Vector s2(5);//而这个就是调用的为特化的,并且进行了实例化,推演。 }

int main() { test1(); return 0; }

“`

类模板的偏特化

偏特化也就是局部特化,就是说一部分特化,一部分不用特化。下面用具体代码说明。

//未特化的版本 template<class T1,class T2> class Data { private: T1 _d1; T2 _d2; public: Data() { cout<<"Data(T1,T2)"<<endl; } }; //局部特化第二个参数 template<class T1> class Data <T1,int> { public: Data() { cout<<"Data(T1,int)"<<endl; } private: T1 _d1; int _d2; }; void test() { Data <double ,int>d1;//调用已经特化的版本 Data <double,double> d2;//掉用未特化的版本 } int main() { test(); return 0; }

类模板的局部特化两个参数为指针或者引用类型

template<class T1,class T2> class Data { private: T1* d3; T2* d4; public: Data() { cout<<"Data(T1,T2)"<<endl; } }; template<class T1,class T2>//指针类型或者引用这个一定要加上后面模板的型参 //class Data<T1&,T2&> class Data <T1*,T2*> { private: T1* d1; //T1& d1; T2* d2; //T2& d2; public: Data() { cout<<"Data(T1*,T2*)"<<endl; } }; void test() { Data<int ,int> d1; Data<int*,int*> d2; //Data<int&,int&>d3; } int main() { test(); return 0; }

*注意:类模板的特化是建立在已经定义的模板的基础上的,也就是上面的代码中未特化的那个模板。 *

模板的优缺点:

优点:模板使代码复用,节省资源。增强了代码的灵活性。

缺点:模板让代码看起来凌乱复杂,不易维护,编译代码时间长;出现模板错误时,错误信息比较凌乱,不易查找错误。

转载请注明原文地址: https://www.6miu.com/read-60193.html

最新回复(0)