目录
分类
一、模板类不继承
(1)代码
(2)分析
(3)运行结果
二、模板类继承普通类
(1)代码
(2)分析
(3)运行结果
三、普通类继承模板类的实例版本
(1)代码
(2)分析
3)运行结果
四、普通类继承模板类(常见)(模板类含通用类型参数)
(1)代码
(2)分析
(3)运行结果
五、模板类继承模板类
(1)代码
(2)分析
(3)运行结果
六、模板类继承模板参数给出的基类(不能是模板类)
(1)代码
(2)分析
(3)运行结果
分类
1)模板类继承普通类(常见)
2)普通类继承模板类的实例版本
3)普通类继承模板类(常见)
4)模板类继承模板类
5)模板类继承模板参数给出的基类(不能是模板类)
一、模板类不继承
(1)代码
#include<iostream>
using namespace std;
//模板类BB
template<class T1,class T2>
class BB
{
public:
T1 m_x;
T2 m_y;
BB(const T1 x,const T2 y):m_x(x),m_y(y){cout<<"调用了BB的构造函数。"<<endl;}
void fun2()const{cout<<"调用了func2()函数:x="<<m_x<<",y="<<m_y<<endl;}
};
int main()
{
BB<int,string>bb(8,"我是一只小猫咪。");
bb.fun2();
return 0;
}
(2)分析
①模板类BB直接实例化,不继承其他类。
(3)运行结果
二、模板类继承普通类
(1)代码
//普通类AA作为基类,BB类作为派生类
#include<iostream>
using namespace std;
//AABB都没有默认的构造函数
//普通类AA
class AA
{
public:
int m_a;
AA(int a):m_a(a){cout<<"调用了AA的构造函数。"<<endl;}
void fun1(){cout<<"调用了func1()函数:m_a="<<m_a<<endl;}
};
//模板类BB
template<class T1,class T2>
class BB:public AA //111111继承普通类
{
public:
T1 m_x;
T2 m_y;
BB(const T1 x,const T2 y,int a):AA(a),m_x(x),m_y(y){cout<<"调用了BB的构造函数。"<<endl;} //222222派生类的构造函数要调用基类的构造函数
void fun2()const{cout<<"调用了func2()函数:x="<<m_x<<",y="<<m_y<<endl;}
};
int main()
{
BB<int,string>bb(8,"我是一只小猫咪。",3);
bb.fun2();
bb.fun1(); //调用基类的func1()函数
return 0;
}
(2)分析
①程序定义了一个普通类AA,模板类BB作为基类继承普通类AA
template<class T1,class T2> //加模板标签
class BB:public AA
②只需要修改派生类BB的构造函数,调用基类AA的构造函数即可;
BB(const T1 x,const T2 y,int a):AA(a),m_x(x),m_y(y)
(3)运行结果
三、普通类继承模板类的实例版本
(1)代码
#include<iostream>
using namespace std;
//AABB都没有默认的构造函数
//模板类BB
template<class T1,class T2>
class BB
{
public:
T1 m_x;
T2 m_y;
BB(const T1 x,const T2 y):m_x(x),m_y(y){cout<<"调用了BB的构造函数。"<<endl;}
void fun2()const{cout<<"调用了func2()函数:x="<<m_x<<",y="<<m_y<<endl;}
};
//普通类AA
class AA:public BB<int,string> //普通类AA继承模板类BB
{
public:
int m_a;
AA(int a,int x,string y):BB(x,y),m_a(a){cout<<"调用了AA的构造函数。"<<endl;} //派生类构造函数调用基类构造函数(初始化列表)
void fun1(){cout<<"调用了func1()函数:m_a="<<m_a<<endl;}
};
int main()
{
AA aa(3,8,"我是一只小猫咪。");
aa.fun1(); //调用派生类函数
aa.fun2(); //调用基类函数
return 0;
}
(2)分析
①普通类AA作为派生类继承模板类BB
AA只是继承BB的某一个实例化版本,普通类继承,没有特殊之处
class AA:public BB<int,string> //不需要加模板标签
②修改派生类AA的构造函数调用基类BB的构造函数即可
AA(int a,int x,string y):BB(x,y),m_a(a)
3)运行结果
四、普通类继承模板类(常见)(模板类含通用类型参数)
(1)代码
#include<iostream>
using namespace std;
//AABB都没有默认的构造函数
//模板类BB
template<class T1,class T2>
class BB
{
public:
T1 m_x;
T2 m_y;
BB(const T1 x,const T2 y):m_x(x),m_y(y){cout<<"调用了BB的构造函数。"<<endl;}
void fun2()const{cout<<"调用了func2()函数:x="<<m_x<<",y="<<m_y<<endl;}
};
//模板类AA
template<class T1,class T2> //11111BB的模板类标签复制下来
class AA:public BB<T1,T2> //22222普通类继承通用模板类
{
public:
int m_a;
AA(int a,T1 x,T2 y):BB<T1,T2>(x,y),m_a(a){cout<<"调用了AA的构造函数。"<<endl;} //333333修改构造函数
void fun1(){cout<<"调用了func1()函数:m_a="<<m_a<<endl;}
};
int main()
{
AA <int,string>aa(3,8,"我是一只小猫咪。"); //4444AA是一个模板类,需要模板标签
aa.fun1();
aa.fun2();
return 0;
}
(2)分析
①普通类AA作为派生类继承模板类BB(非实例化)
要保留BB的通用类型,就需要把AA变成模板类
template<class T1,class T2> //BB的模板类标签复制下来
class AA:public BB<T1,T2> //普通类继承通用模板类
②修改派生类AA的构造函数调用基类BB的构造函数即可
AA(int a,T1 x,T2 y):BB<T1,T2>(x,y),m_a(a)
(3)运行结果
五、模板类继承模板类
(1)代码
#include<iostream>
using namespace std;
//AABB都没有默认的构造函数
//模板类BB
template<class T1,class T2>
class BB
{
public:
T1 m_x;
T2 m_y;
BB(const T1 x,const T2 y):m_x(x),m_y(y){cout<<"调用了BB的构造函数。"<<endl;}
void fun2()const{cout<<"调用了func2()函数:x="<<m_x<<",y="<<m_y<<endl;}
};
//普通类AA
template<class T1,class T2>
class AA:public BB<T1,T2>
{
public:
int m_a;
AA(int a,T1 x,T2 y):BB<T1,T2>(x,y),m_a(a){cout<<"调用了AA的构造函数。"<<endl;}
void fun1(){cout<<"调用了func1()函数:m_a="<<m_a<<endl;}
};
//模板类CC
template<class T,class T1,class T2> //11111111CC类模板标签增加两个通用类型参数
class CC:public BB<T1,T2> //22222222CC类继承BB类
{
public:
T m_a;
CC(const T a,const T1 x,const T2 y):BB<T1,T2>(x,y),m_a(a){cout<<"调用了CC的构造函数。\n"<<endl;} //CC类构造函数调用基类BB构造函数
void fun3(){cout<<"调用了fun3()函数:m_a="<<m_a<<endl;}
};
int main()
{
CC <int,int,string>cc(3,8,"我是一只小猫咪。");
cc.fun3();
cc.fun2();
return 0;
}
(2)分析
①增加一个模板类CC
template<class T>
class CC
{
public:
T m_a;
CC(const T a):m_a(a){cout<<"调用了CC的构造函数。\n"<<endl;}
void fun3(){cout<<"调用了fun3()函数:m_a="<<m_a<<endl;}
};
②模板类CC继承BB
template<class T,class T1,class T2> //CC类模板标签增加两个通用类型参数
class CC:public BB<T1,T2> //CC类继承BB类
②修改派生类CC的构造函数调用基类BB的构造函数即可;
CC(const T a,const T1 x,const T2 y):BB<T1,T2>(x,y),m_a(a)
(3)运行结果
六、模板类继承模板参数给出的基类(不能是模板类)
(1)代码
#include<iostream>
using namespace std;
//普通类AA
class AA
{
public:
AA(){cout<<"调用了AA的构造函数AA()。"<<endl;}
AA(int a){cout<<"调用了AA的构造函数AA(int a)。"<<endl;}
};
//普通类BB
class BB
{
public:
BB(){cout<<"调用了BB的构造函数BB()。"<<endl;}
BB(int a){cout<<"调用了BB的构造函数BB(int a)。"<<endl;}
};
//普通类CC
class CC
{
public:
CC(){cout<<"调用了CC的构造函数CC()。"<<endl;}
CC(int a){cout<<"调用了CC的构造函数CC(int a)。"<<endl;}
};
//模板类DD
template<class T>
class DD
{
public:
DD(){cout<<"调用了DD的构造函数DD()。"<<endl;}
DD(int a){cout<<"调用了DD的构造函数DD(int a)。"<<endl;}
};
//模板类EE
template<class T>
class EE:public T
{
public:
EE():T(){cout<<"调用了EE的构造函数EE()。"<<endl;}
EE(int a):T(a){cout<<"调用了EE的构造函数EE(int a)。"<<endl;}
};
int main()
{
EE<AA>ea1;//AA作为基类
EE<BB>eb1;//BB作为基类
EE<CC>ec1;//CC作为基类
EE<DD<int> >ed1; //DD<int>作为基类,模板类作为基类时,必须明确指出模板类型参数
//EE<DD>ed1; //DD作为基类,错误
return 0;
}
(2)分析
①EE是模板类,有一个通用模板类型参数,在继承时T可以是普通类,也可以是模板类;
②但是在继承模板类的时候需要指明基类的通用类型参数。
EE<DD<int> >ed1; //DD<int>(类名)作为基类,模板类作为基类时,必须明确指出模板类型参数
//EE<DD>ed1; //DD作为基类,错误