C++温故补缺(十三):模板

C++模板

模板是泛型的基础,泛型编程就是一种独立于任何特殊类型的方式编写代码。模板就是创建泛型类或泛型函数的蓝图。STL库中的几个数据结构(vector,list,map等)以及算法都使用了泛型。

函数模板

格式:template <typename type> return-type function-name(parameter list){//函数体}

模板用到的关键字是template,其后跟的就是后续可以指定的模板类型,return-type是返回值类型,后面是函数名和参数列表,和普通函数别无二致。

就是多了template关键字和一个可以后续修改的模板类型

例子:

#include<iostream>
using namespace std;

template <typename T> T Max(T x,T y){
    return x<y?y:x;
}
int main(){
    int a=12,b=15;
    float a1=1.2,b1=1.5;
    cout<<Max(a,b)<<endl;
    cout<<Max(a1,b1)<<endl;
}

如上,Max函数可以作用于不同的类型的参数,它会根据参数的类型自动转换模板类型T的类型,T只是一个名字,用来标志模板的类型。

函数的参数以及返回值也是可以为T类型。

T的类型在传参时会自动确定,但也可以显式指定类型:Max<int>()

类模板

格式:template <class type> class class-name{};

类似于函数模板,<class type>就是用来定义类模板的,后续可以指定为不同的类型

例子:

#include<iostream>
#include<string.h>
using namespace std;

class people{
    protected:
        string name;
    public:
        people(){name="";}
        people(string name){this->name=name;}
};
class student:public people{
    protected:
        int sno;
    public:
        student(){sno=-1;}
        student(int no,string name):people(name){sno=no;}
        int getno(){return sno;}
        string getname(){return name;}
};
class teacher:public student{
    public:
        teacher(int no,string name):student(no,name){}
        int getno(){return sno;}
        string getname(){return name;}
};


template <class T> class Item{
    private:
        T* tp;
    public:
        Item(T* tp){
            this->tp=tp;
        }
        ~Item(){
            delete tp;
        }
        void getInformation(){
            if(typeid(T)==typeid(student)){
                cout<<"学号:"<<tp->getno()<<" ";
                cout<<"学生姓名:"<<tp->getname()<<endl;
            }else if(typeid(T)==typeid(teacher)){
                cout<<"工号:"<<tp->getno()<<" ";
                cout<<"教师姓名:"<<tp->getname()<<endl;
            }
        }

}; 
int main(){
    Item i(new student(2014114,"张璇"));
    i.getInformation();
    Item<teacher> i1(new teacher(2001401,"李朱强"));
    i1.getInformation();

}

类模板中用到的类T的不同情况要有相同的字段,因为模板的解释是发生在编译阶段的,如果用了不同的字段,则会因为类和字段不对应找不到成员,导致编译不通过。

如上的例子中,teacher和student有相同的成员函数getno()和getname(),所以在模板类中调用两个函数可以自动识别,如果两个函数定义成不同的,如:

class student:public people{
    protected:
        int sno;
    public:
        student(){sno=-1;}
        student(int no,string name):people(name){sno=no;}
        int getSno(){return sno;}
        string getSname(){return name;}
};
class teacher:public student{
    public:
        teacher(int no,string name):student(no,name){}
        int getTno(){return sno;}
        string getTname(){return name;}
};
template <class T> class Item{
    private:
        T* tp;
    public:
        Item(T* tp){
            this->tp=tp;
        }
        ~Item(){
            delete tp;
        }
        void getInformation(){
            if(typeid(T)==typeid(student)){
                cout<<"学号:"<<tp->getSno()<<" ";
                cout<<"学生姓名:"<<tp->getSname()<<endl;
            }else if(typeid(T)==typeid(teacher)){
                cout<<"工号:"<<tp->getTno()<<" ";
                cout<<"教师姓名:"<<tp->getTname()<<endl;
            }
        }

};

那么在模板中,确定模板类型后,假设为student,就会因为student没有getTno()和getTname()字段而无法通过编译,因为模板T识别为student是发生在编译阶段的,一旦确定为student,模板类中所有的T都会被替换成student,所以就出现"student类无getTno()和getTname()成员"的错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值