我们之前实现过顺序表,链表,为了方便以后通用,我们会定义一个新的 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; //这样就可以实现改变数组的大小。 }模板特化不同于模板的实例化,模板参数在某种特定类型下的具体实现称为模板的特化。模板特化有时也称之为模板的具体化,分别有函数模板特化和类模板特化。 特化又可以分为:偏特化,全特化。
“` //下面这个是未特化的版本 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; }*注意:类模板的特化是建立在已经定义的模板的基础上的,也就是上面的代码中未特化的那个模板。 *