第七章 2.泛型编程(模板)

作用:提高程序可复用性,程序编译时自动生成相应函数

函数模板和类模板中的类型参数表中classtypename可相互替换

函数模板

  1. 格式

    template<class T1,class T2,...>
    返回值类型 模板名(参数表){
        函数体
    }
    
  2. 匹配顺序

    • 参数完全匹配的普通函数
    • 参数完全匹配的模板函数(匹配模板函数时,不会进行自动类型转换)
    • 实参经过自动类型转换 后匹配的普通函数
    • 上述匹配均不存在则报错
  3. 可通过模板函数名<类型>不通过参数实例化

  4. 模板函数也可以重载,只要形参表或类型参数表不同即可

  5. 支持函数指针类型

    #include<iostream>
    using namespace std;
    template<class T,class Pred>
    void Map(T s,T e,T x,Pred op){
        for(;s!=e;s++,x++)  *x=op(*s);
    }
    double Square(double x){return x*x;}
    int Cube(int x){return x*x*x;}
    
    template<class T>
    void Output(T &arr){
        for(int i=0;i<(sizeof(arr)/sizeof(*arr));++i) cout<<arr[i]<<" ";
        cout<<endl; 
    }
    int main(){
        int a[5]={1,2,3,4,5},b[5];
        double d[5]={1.1,2.2,3.3,4.4,5.5},c[5];
        Map(a,a+5,b,Square);
        Output(b);
        Map(a,a+5,b,Cube);
        Output(b);
        Map(d,d+5,c,Square);
        Output(c);
        return 0;
    }
    

类模板

  1. 定义方式:

    template<class T1,class T2,...>
    class ClassName{
        Member Function;
        Member Variable;
        ReturnType Func(Parameter Table);
    }
    //在类外定义成员函数
    template<class T1,class T2,...>
    ReturnType ClassName<T1,T2,...>::Func(Parameter Table){ ... }
    //通过类模板定义对象
    ClassName<T1,T2,...> Obj;
    
    //类模板的类型参数表可以包含非类型参数
    template<class T,int size>
    class Count{
        public:
            T arr[size];
            void Output(){
                for(int i=0;i<size;++i) cout<<arr[i]<<endl;
            }
    }
    Count<double,50> test;
    
  2. 在类模板内定义函数模板

    template<class T1>
    class Test{
        public:
            template<class T2>
            void Func(T2 a){
                cout<<a<<endl;
            }
    };
    int main(){
        Test<int> a;
        a.Func("Test");
        return 0;
    }
    
  3. 编译器由类模板生成类的过程称为类的实例化,生成的类称为模板类

  4. 同一类模板生成的不同模板类不兼容(即两个独立不同的类型)

类模板与派生

  1. 类模板从类模板派生

  2. 类模板从模板类派生

  3. 类模板从普通类派生

  4. 普通类从模板类派生

    template<class T1,class T2>
    class A{
        T1 v1;
        T2 v2;
    }
    //类模板从类模板中派生
    template<class T1,class T2> 
    class B:public A<T2,T1>{ //A模板实例化顺序不一定相同
        T1 v3;
        T2 v4;
    }
    //类模板从模板类派生
    template<class T>
    class B:public A<int,double>{}
    //类模板从普通类中派生
    class C{int a;}
    template<class T> 
    class B:public C{
        T val;
    }
    //普通类从模板类中派生
    class D:public A<int,double>{ int a;}
    

类模板与友元

  1. 函数、类、类成员函数作为类模板友元

    void Func1(){}
    class A{
        int a;
        public:
        void Func(){}
    }
    template<class T>
    class B{
        T a;
        public:
        friend void Func1(); //友元函数
        friend class A; //友元类
        friend void A::Func(); //类成员函数作为友元类
    }
    
  2. 函数模板作为类模板友元

    template<typename T1,typename T2>
    class Pair{
        T1 key;
        T2 value;
    public:
         Pair(T1 k,T2 v):key(k),value(v){}
         //函数模板作为类模板友元
         template<class T3,class T4> //不能写T1、T2,否则可能报错
         friend ostream& operator<< (ostream &out,const Pair<T3,T4> &p); 
    };
    template<class T1,class T2>
    ostream& operator<< (ostream& out,const Pair<T1,T2> &p){
        return out<<"("<<p.key<<","<<p.value<<")"<<endl;
    }
    
  3. 函数模板作为类的友元

    class A{
        int v;
    public:
        A(int n):v(n){}
        template<class T>
        friend void Print(const T& p); 
    }
    template<class T>
    void Print(const T& p){cout<<p.v;}
    int main(){
        A a(10);
        Print(a);
        return 0;
    }
    
  4. 类模板作为类模板友元

    template<class T>
    class A{
        T v;
        public:
        A(int n):v(n){}
        template<class T2> //不能写成T,可能报错
        friend class B;
    }
    template<class T>
    class B{
       public:
            void Func(){
                A<int> o(10);
                cout<<o.v<<endl;
            }
        }
    

类模板中的static成员

  1. 统一类模板的不同类型的实例static相互独立,相同类型示例共用

    class A{
        static int count;
        public:
            void PrintCnt(){ cout<<count<<endl; }
            A(){count++;}
            ~A(){count--;}
            A(A&){count++;}
    };
    template<> int A<int>::count=0; //类模板中static变量声明方式
    template<> int A<double>::count=0;
    int main(){
        A<int> a,c;
        a.PrintCnt(); //2
        A<double> b;
        b.PrintCnt(); //1
        return 0;
    }
    

原文链接: https://www.cnblogs.com/DreamEagle/p/12632072.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    第七章 2.泛型编程(模板)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/339922

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午12:20
下一篇 2023年3月2日 上午12:20

相关推荐