不可或缺 Windows Native (22) - C++: 多重继承, 虚基类
不可或缺 Windows Native (22) - C++: 多重继承, 虚基类
作者:webabcd
介绍
不可或缺 Windows Native 之 C++
- 多重继承
- 虚基类
示例
1、基类 1
CppBase1.h
#pragma once #include <string> #include "CppBaseVirtual.h" using namespace std; namespace NativeDll { // virtual 代表 CppBaseVirtual 是 CppBase1 的虚基类(虚基类是在声明派生类时,指定继承方式时声明的) class CppBase1 : virtual public CppBaseVirtual { protected: string Name; float Salary; public: CppBase1(int number, string name, float salary); }; }
CppBase1.cpp
/* * 基类 1 */ #include "pch.h" #include "CppBase1.h" using namespace NativeDll; CppBase1::CppBase1(int number, string name, float salary) :CppBaseVirtual(number), Name("cppbase1 " + name), Salary(salary) { }
2、基类 2
CppBase2.h
#pragma once #include <string> #include "CppBaseVirtual.h" using namespace std; namespace NativeDll { // virtual 代表 CppBaseVirtual 是 CppBase2 的虚基类(虚基类是在声明派生类时,指定继承方式时声明的) class CppBase2 : virtual CppBaseVirtual { protected: string Name; int Age; public: CppBase2(int number, string name, int age); }; }
CppBase2.cpp
/* * 基类 2 */ #include "pch.h" #include "CppBase2.h" using namespace NativeDll; CppBase2::CppBase2(int number, string name, int age) :CppBaseVirtual(number), Name("cppbase2 " + name), Age(age) { }
3、虚基类
CppBaseVirtual.h
#pragma once #include <string> using namespace std; namespace NativeDll { class CppBaseVirtual { private: int Number; public: CppBaseVirtual(int number); }; }
CppBaseVirtual.cpp
/* * 用于演示虚基类 * * 注: * 1、虚基类并不是在声明基类时声明的,而是在声明派生类时,指定继承方式时声明的 * 2、一个基类可以在生成一个派生类时作为虚基类,也可以在生成一个派生类时不作为虚基类 */ #include "pch.h" #include "CppBaseVirtual.h" using namespace NativeDll; CppBaseVirtual::CppBaseVirtual(int number) :Number(number) { }
4、派生类
CppDerived.h
#pragma once #include <string> #include "CppBase1.h" #include "CppBase2.h" using namespace std; namespace NativeDll { class CppDerived : public CppBase1, public CppBase2 { public: CppDerived(int number, string name, float salary, int age); string Show(); }; }
CppDerived.cpp
/* * 派生类 * * * 在多重继承的情况下: * 1、如果 A 是 B C D E 的基类,F 同时继承了 B C D E,那么实例化 F 时会保存 4 份 A 成员 * 2、如果 A 是 B 的基类,A 是 C D E 的虚基类(虚基类会使得在继承间接共同基类时只保留一份成员),F 同时继承了 B C D E,那么实例化 F 时会保存 2 份 A 成员(从 C D E 的路径上保留一份,从 B 的路径上保留一份) * * * 本例中: * 1、CppBaseVirtual 是 CppBase1 和 CppBase2 的虚基类 * 2、CppDerived 继承了 CppBase1 和 CppBase2(多重继承) * 3、此种情况,实例化 CppDerived 只会保留一份 CppBaseVirtual 成员(因为 CppBaseVirtual 是 CppBase1 和 CppBase2 的虚基类) * 4、C++ 编译器只会执行最后的派生类(CppDerived)对虚基类(CppBaseVirtual)的构造函数的调用,而忽略虚基类的直接派生类(CppBase1 和 CppBase2)对虚基类的构造函数的调用,这就保证了虚基类的数据成员不会被多次初始化 */ #include "pch.h" #include "CppDerived.h" #include "cppHelper.h" using namespace NativeDll; // 在无虚基类的情况下,派生类的构造函数中只需负责对其直接基类初始化 // 如果有虚基类,且虚基类中定义了带参数的构造函数,且没有定义默认构造函数,那么派生类不仅要负责对其直接基类进行初始化,还要负责对虚基类初始化 CppDerived::CppDerived(int number, string name, float salary, int age) :CppBaseVirtual(number), CppBase1(number, name, salary), CppBase2(number, name, age) { } string CppDerived::Show() { // 关于多重继承的二义性(ambiguous),如果派生类同时继承的多个基类有相同的成员,则调用这些成员时需显式指定其基类 return CppBase1::Name + " " + float2string(Salary) + " " + int2string(Age); // 另外:当然,如果派生类与多个基类有相同成员的话,那么基类中的这些与派生类相同的成员都会被隐藏掉(即派生类中的成员会覆盖基类中的成员) }
5、示例
CppClass6.h
#pragma once #include <string> using namespace std; namespace NativeDll { class CppClass6 { public: string Demo(); }; }
CppClass6.cpp
/* * 多重继承(multiple inheritance), 虚基类(virtual base class) */ #include "pch.h" #include "CppClass6.h" #include "CppDerived.h" using namespace NativeDll; string CppClass6::Demo() { CppDerived derived(0, "webabcd", 100.0f, 35); string result = derived.Show(); // cppbase1 webabcd 100.00 35 return result; }
OK
[源码下载]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?