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()成员"的错误。
本文来自博客园,作者:Tenerome,转载请注明原文链接:https://www.cnblogs.com/Tenerome/p/cppreview13.html