虚基类的作用:消除二义性
前因:
1.C++中多重继承,即一个派生类可以有多个基类。如果多个基类有同名成员或同名函数,派生类对象对其访问时会产生二义性。
举例:

#include <iostream> using namespace std; class Base1 { public: Base1(int var){cout << "Base1" << endl; }; int var; void fun() { cout << "Base1::fun()" << endl; } }; class Base2 { public: Base2(int var){cout << "Base2" << endl;}; int var; void fun() { cout << "Base2::fun()" << endl; } }; class Derived : public Base1, public Base2 { public: Derived(int var) : Base1(var), Base2(var){cout << "Derived" << endl; }; //int var; //void fun() { cout << "Derived::fun()" << endl; } }; int main() { Derived d(1); d.var = 2; d.fun(); //cout<<"d.var = " <<d.var<<endl; return 0; }
输出:
2.如果多个基类又有一个共同的基类,则在最终的派生类中会保留多份同名的共同基类的数据成员。
避免二义性的访问方法: c.A::display( );
为了避免派生类中保留多份同名成员,C++提供了虚基类(virtual base class)的方法,在派生类中只保留一份成员。
声明:class 派生类名: virtual 继承方式 基类名
Class A //声明基类A
{...};
Class B1 : virtual public A //声明派生类B1,A是B1的虚基类
{...};
Class B2 : virtual public A //声明派生类B2,A是B2的虚基类
{...};
Class C : public B1, public B2 //声明派生类C,多继承B1和B2,只继承A一次
{...};
注意:
虚基类并不是在声明基类时声明的,而是在声明派生类时,指定继承方式时声明的。因为一个基类可以在生成一个派生类时作为虚基类,而在生成另一个派生类时不作为虚基类。
实例:

#include <iostream> using namespace std; class Base0 { public: Base0(int var) : var0(var) { cout << "Base0" << endl;}; int var0; void fun0() { cout << "Member of Base0" << endl; } }; class Base1 : virtual public Base0 { public: Base1(int var) : Base0(var){cout << "Base1" << endl; }; int var1; }; class Base2 : virtual public Base0 { public: Base2(int var) : Base0(var){cout << "Base2" << endl;}; int var2; }; class Derived : public Base1, public Base2 { public: Derived(int var) : Base0(var), Base1(var), Base2(var), var(0){cout << "Derived" << endl; }; int var; void fun() { cout << "Member of Derived" << endl; } }; int main() { Derived d(1); d.var0 = 2; d.fun0(); cout<<"d.var0 = " <<d.var0<<endl; cout<<"d.var1 = " <<d.var1<<endl; cout<<"d.var2 = " <<d.var2<<endl; cout<<"d.var = " <<d.var<<endl; return 0; }
输出:
注意:
1.在整个继承结构中,直接或间接继承虚基类的所有派生类,都必须在构造函数的成员初始化表中给出对虚基类的构造函数的调用;
2.在建立对象时,只有最后派生类的构造函数调用虚基类的构造函数,而忽略虚基类的其他派生类,这样就保证了虚基类的数据成员不会被多次初始化。
参考来源:
https://www.cnblogs.com/yiranlaobaitu/p/3764422.html
https://blog.csdn.net/happyjacob/article/details/80781093
PS:
https://blog.csdn.net/qq_28114615/article/details/88077009 这篇博客介绍了虚继承的内存分布,非常详细
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗