欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > C++ —— 模板类与继承

C++ —— 模板类与继承

2025/5/7 16:38:42 来源:https://blog.csdn.net/MaoSiri/article/details/144696392  浏览:    关键词:C++ —— 模板类与继承

C++ —— 模板类与继承

  • 模板类继承普通类(常见)
  • 普通类继承模板类的实例化版本
  • 普通类继承模板类(常见)
  • 模板类继承模板类
  • 模板类继承模板参数给出的基类(不能是模板类)

模板类继承普通类(常见)

AA和模板类BB的示例代码如下(两个类目前都没有默认的构造函数):

#include <iostream>
using namespace std;class AA {
public:int m_a;AA(int a):m_a(a) {cout << "AA构造函数" << endl;} void func1() {cout << "AA::func1, m_a = " << m_a << endl;}
};template <class T1, class T2>
class BB {
public:T1 m_x;T2 m_y;BB(T1 x, T2 y): m_x(x), m_y(y) {cout << "BB构造函数" << endl;}void func2() {cout << "BB::func2, m_x = " << m_x << ", m_y = " << m_y << endl;}
};
// AA和BB都没有默认的构造函数int main() {BB<int, string> bb(10, "hello");bb.func2();return 0;
}

运行结果如下:

BB构造函数
BB::func2, m_x = 10, m_y = hello

现在修改代码,让类BB继承AA。需要考虑的是,在继承时,派生类如何构造基类(要在派生类BB的构造函数的初始化列表中,指明基类的构造函数)。修改后的代码如下:

#include <iostream>
using namespace std;class AA {
public:int m_a;AA(int a):m_a(a) {cout << "AA构造函数" << endl;} void func1() {cout << "AA::func1, m_a = " << m_a << endl;}
};template <class T1, class T2>
class BB: public AA {// 需要考虑,继承的时候,派生类如何构造基类。
public:T1 m_x;T2 m_y;// 指明基类的构造函数,AA的构造需要一个参数,从外面传给它。BB(const T1 x, const T2 y, int a): AA(a), m_x(x), m_y(y) {cout << "BB构造函数" << endl;}void func2() {cout << "BB::func2, m_x = " << m_x << ", m_y = " << m_y << endl;}
};int main() {// 创建bb对象时,增加一个参数,传递给基类AA的构造函数。BB<int, string> bb(10, "hello", 123);bb.func2();bb.func1(); // 调用基类AA的成员函数return 0;
}

运行效果如下:

AA构造函数
BB构造函数
BB::func2, m_x = 10, m_y = hello
AA::func1, m_a = 123

普通类继承模板类的实例化版本

模板类有很多实例化版本,供子类继承。现在让AA继承BB<int, string>实例化版本。示例代码如下:

#include <iostream>
using namespace std;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 func2() {cout << "BB::func2, m_x = " << m_x << ", m_y = " << m_y << endl;}
};class AA:public BB<int, string> {// 派生类
public:int m_a;AA(int a, int x, string y):BB(x, y), m_a(a) {cout << "AA构造函数" << endl;} void func1() {cout << "AA::func1, m_a = " << m_a << endl;}
};int main() {AA aa(123, 456, "xxxxxxx");aa.func1();aa.func2();return 0;
}

运行效果如下:

BB构造函数
AA构造函数
AA::func1, m_a = 123
BB::func2, m_x = 456, m_y = xxxxxxx

普通类继承模板类(常见)

AA只继承BB的某一个实例化版本很多时候功能是不够用的,故需要AA继承BB的通用特性。所以要把AA变成模板类,示例代码如下:

#include <iostream>
using namespace std;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 func2() {cout << "BB::func2, m_x = " << m_x << ", m_y = " << m_y << endl;}
};template <class T1, class T2> // 模板类
class AA:public BB<T1, T2> {
public:int m_a;// 修改后的构造函数AA(int a, const T1 x, const T2 y):BB<T1, T2>(x, y), m_a(a) {cout << "AA构造函数" << endl;} void func1() {cout << "AA::func1, m_a = " << m_a << endl;}
};int main() {// AA也是模板类了,需要指定模板参数。AA<int, string> aa(111, 222, "你好!");aa.func1();aa.func2();return 0;
}

运行结果如下:

BB构造函数
AA构造函数
AA::func1, m_a = 111
BB::func2, m_x = 222, m_y = 你好!

模板类继承模板类

普通类要继承模板类,必须先把自己变成模板类。若派生类本身就是模板类,则增加基类的通用类型参数就可以了。假设现在有一个模板类CC,示例代码如下:

template <class T>
class CC{
public:T m_a;CC(const T a): m_a(a) {cout << "CC构造函数" << endl;}void func1() {cout << "CC::func1, m_a = " << m_a << endl;}
};

现在模板类CC要继承模板类BB,示例代码如下:

#include <iostream>
using namespace std;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 func2() {cout << "BB::func2, m_x = " << m_x << ", m_y = " << m_y << endl;}
};// 增加模板参数
template <class T, class T1, class T2>
class CC:public BB<T1, T2>{
public:T m_a;// 修改后的构造函数CC(const T a, const T1 x, const T2 y): BB<T1, T2>(x, y), m_a(a) {cout << "CC构造函数" << endl;}void func3() {cout << "CC::func3, m_a = " << m_a << endl;}
};int main() {CC<int, string, int> cc(100, "你好!", 333);cc.func3();cc.func2();return 0;
}

运行结果如下:

BB构造函数
CC构造函数
CC::func3, m_a = 100
BB::func2, m_x = 你好!, m_y = 333

模板类继承模板参数给出的基类(不能是模板类)

示例代码如下:

#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。class AA {
public:AA()         { cout << "调用了AA的构造函数AA()。\n"; }AA(int a) { cout << "调用了AA的构造函数AA(int a)。\n"; }
};class BB {
public:BB()         { cout << "调用了BB的构造函数BB()。\n"; }BB(int a) { cout << "调用了BB的构造函数BB(int a)。\n"; }
};class CC {
public:CC()         { cout << "调用了CC的构造函数CC()。\n"; }CC(int a) { cout << "调用了CC的构造函数CC(int a)。\n"; }
};template<class T>
class DD {
public:DD()         { cout << "调用了DD的构造函数DD()。\n"; }DD(int a) { cout << "调用了DD的构造函数DD(int a)。\n"; }
};template<class T>
class EE : public T {          // 模板类继承模板参数给出的基类。
public:EE() :T()           { cout << "调用了EE的构造函数EE()。\n"; }EE(int a) :T(a) { cout << "调用了EE的构造函数EE(int a)。\n"; }
};int main()
{EE<AA> ea1;                 // AA作为基类。EE<BB> eb1;                 // BB作为基类。EE<CC> ec1;                 // CC作为基类。EE<DD<int>> ed1;      // EE<int>作为基类。// EE<DD> ed1;                // DD作为基类,错误。
}

感谢浏览,一起学习!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词