zoukankan      html  css  js  c++  java
  • 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;
    }

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

    模板的优缺点:

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

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

  • 相关阅读:
    C++ Primer 学习笔记
    闷热的北京
    EasyUI实现购物车、菜单和窗口栏等最常用的用户界面功能.
    详细解读-this-关键字在全局、函数、对象、jQuery等中的基础用法!
    对于JavaScript原生的JS
    关于JavaScript原生的JS。工作接近一年,发现对于原生JS的基础内容总是不够掌握,特定抽出三个周的周末,结合本人的工作经验还有菜鸟教程及w3school的基础内容等整理了如下内容。对JS的常用知识进行概括!希望对大家能够有所帮助。
    最简单实用的JQuery实现banner图中的text打字动画效果!!!
    一路慢行的JavaScript之旅(add)!!!
    一路慢行的CSS之旅
    一路慢行的HTML5之旅!
  • 原文地址:https://www.cnblogs.com/chan0311/p/9427353.html
Copyright © 2011-2022 走看看