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.类模板在实例化时必须显式地指明数据类型,赋值号两边也要指明具体的数据类型,且要保持一致

  • 相关阅读:
    GPON和820.1p学习及资料(zt)
    modelsim(3)
    JTAG 学习 -SVF格式
    看来人工智能不可阻挡,将和网络与计算机一样服务于各行各业!
    【管理心得之二十六】职场中的“武功”
    【管理心得之二十五】组织中的骂名 ----------墙头草
    【管理心得之二十四】成功乃失败之母
    【管理心得之二十三】道是道,非常道。名可名,非常名。
    【管理心得之二十二】小人物 仰视 大授权
    【管理心得之二十一】管得少就是管得好
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/7110249.html
Copyright © 2011-2022 走看看