C++模板(下)

模板类

<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;
}

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

模板的优缺点:

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

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

posted @ 2017-05-06 17:37  chan0311  阅读(82)  评论(0编辑  收藏  举报