zoukankan      html  css  js  c++  java
  • C++语言基础(18)-模板

    Java中的泛型编程可以极大的提升编程的效率,比如在android中查找一个控件的ID:标准写法为:

    TextView tv_text = (TextView)findViewById(R.id.tv_text);

    或者:

    ImageView iv_img = (ImageView)findViewById(R.id.iv_img);

    因为同为查询控件ID,所以上面的写法可以采用泛型编程精简为:

    protected final <T extends View> T getView(int id) {
            return (T) findViewById(id);
    }

    这样在下次使用的时候就可以写成这样:

    TextView tv_text = getView(R.id.tv_text);

    C++中也有类似的东西,不过名字变了,叫模板(template)

    一.函数模板

    例:交换两个相同类型变量的值

    原始写法:

    //交换 int 变量的值
    void Swap(int *a, int *b){
        int temp = *a;
        *a = *b;
        *b = temp;
    }
    
    //交换 float 变量的值
    void Swap(float *a, float *b){
        float temp = *a;
        *a = *b;
        *b = temp;
    }
    
    //交换 char 变量的值
    void Swap(char *a, char *b){
        char temp = *a;
        *a = *b;
        *b = temp;
    }
    
    //交换 bool 变量的值
    void Swap(bool *a, bool *b){
        char temp = *a;
        *a = *b;
        *b = temp;
    }

    使用模板后的写法:

    #include <iostream>
    using namespace std;
    
    template<typename T> void Swap(T *a, T *b){
        T temp = *a;
        *a = *b;
        *b = temp;
    }
    
    int main(){
        //交换 int 变量的值
        int n1 = 100, n2 = 200;
        Swap(&n1, &n2);
        cout<<n1<<", "<<n2<<endl;
       
        //交换 float 变量的值
        float f1 = 12.5, f2 = 56.93;
        Swap(&f1, &f2);
        cout<<f1<<", "<<f2<<endl;
       
        //交换 char 变量的值
        char c1 = 'A', c2 = 'B';
        Swap(&c1, &c2);
        cout<<c1<<", "<<c2<<endl;
       
        //交换 bool 变量的值
        bool b1 = false, b2 = true;
        Swap(&b1, &b2);
        cout<<b1<<", "<<b2<<endl;
    
        return 0;
    }

    修改成引用:

    #include <iostream>
    using namespace std;
    
    template<typename T> void Swap(T &a, T &b){
        T temp = a;
        a = b;
        b = temp;
    }
    
    int main(){
        //交换 int 变量的值
        int n1 = 100, n2 = 200;
        Swap(n1, n2);
        cout<<n1<<", "<<n2<<endl;
       
        //交换 float 变量的值
        float f1 = 12.5, f2 = 56.93;
        Swap(f1, f2);
        cout<<f1<<", "<<f2<<endl;
       
        //交换 char 变量的值
        char c1 = 'A', c2 = 'B';
        Swap(c1, c2);
        cout<<c1<<", "<<c2<<endl;
       
        //交换 bool 变量的值
        bool b1 = false, b2 = true;
        Swap(b1, b2);
        cout<<b1<<", "<<b2<<endl;
    
        return 0;
    }

    例:求三个数最大值:

    #include <iostream>
    using namespace std;
    
    //声明函数模板
    template<typename T> T max(T a, T b, T c);
    
    int main( ){
        //求三个整数的最大值
        int i1, i2, i3, i_max;
        cin >> i1 >> i2 >> i3;
        i_max = max(i1,i2,i3);
        cout << "i_max=" << i_max << endl;
    
        //求三个浮点数的最大值
        double d1, d2, d3, d_max;
        cin >> d1 >> d2 >> d3;
        d_max = max(d1,d2,d3);
        cout << "d_max=" << d_max << endl;
    
        //求三个长整型数的最大值
        long g1, g2, g3, g_max;
        cin >> g1 >> g2 >> g3;
        g_max = max(g1,g2,g3);
        cout << "g_max=" << g_max << endl;
    
        return 0;
    }
    
    //定义函数模板
    template<typename T>  //模板头,这里不能有分号
    T max(T a, T b, T c){ //函数头
        T max_num = a;
        if(b > max_num) max_num = b;
        if(c > max_num) max_num = c;
        return max_num;
    }

    运行结果:

    12  34  100
    i_max=100
    73.234  90.2  878.23
    d_max=878.23
    344  900  1000
    g_max=1000

    总结一下,函数模板的基本语法为:

    template <typename 类型参数1 , typename 类型参数2 , ...> 返回值类型  函数名(形参列表){
        //在函数体中可以使用类型参数
    }

    二.类模板

    类模板的声明与函数模板的声明类似:

    template<typename 类型参数1 , typename 类型参数2 , …> class 类名{
        //TODO:
    };

    示例代码:

    #include <iostream>
    using namespace std;
    
    template<class T1, class T2>  //这里不能有分号
    class Point{
    public:
        Point(T1 x, T2 y): m_x(x), m_y(y){ }
    public:
        T1 getX() const;  //获取x坐标
        void setX(T1 x);  //设置x坐标
        T2 getY() const;  //获取y坐标
        void setY(T2 y);  //设置y坐标
    private:
        T1 m_x;  //x坐标
        T2 m_y;  //y坐标
    };
    
    template<class T1, class T2>  //模板头
    T1 Point<T1, T2>::getX() const /*函数头*/ {
        return m_x;
    }
    
    template<class T1, class T2>
    void Point<T1, T2>::setX(T1 x){
        m_x = x;
    }
    
    template<class T1, class T2>
    T2 Point<T1, T2>::getY() const{
        return m_y;
    }
    
    template<class T1, class T2>
    void Point<T1, T2>::setY(T2 y){
        m_y = y;
    }
    
    int main(){
        Point<int, int> p1(10, 20);
        cout<<"x="<<p1.getX()<<", y="<<p1.getY()<<endl;
     
        Point<int, char*> p2(10, "东京180度");
        cout<<"x="<<p2.getX()<<", y="<<p2.getY()<<endl;
     
        Point<char*, char*> *p3 = new Point<char*, char*>("东京180度", "北纬210度");
        cout<<"x="<<p3->getX()<<", y="<<p3->getY()<<endl;
    
        return 0;
    }

    输出结果:

    x=10, y=20
    x=10, y=东京180度
    x=东京180度, y=北纬210度

    注意:

    1.在对类模板的成员函数进行定义时,除了 template 关键字后面要指明类型参数,类名 Point 后面也要带上类型参数,只是不加 typename 关键字了

    2.类模板在实例化时必须显式地指明数据类型,赋值号两边也要指明具体的数据类型,且要保持一致

  • 相关阅读:
    微软外服 AlI In One
    js 循环多次和循环一次的时间的性能对比 All In One
    vue inject All In One
    Excel 表格数据倒置 All In One
    SVG tickets All In One
    OH MY ZSH All In One
    js array for loop performance compare All In One
    mac terminal show You have new mail All In one
    新闻视频 26 制作母版页
    转自牛腩 母版页和相对路径
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/7110249.html
Copyright © 2011-2022 走看看