虚继承解决的问题:
虚继承主要是为了解决C++的菱形继承的时候其父类的公共基类有多个副本的问题,这个问题会造成资源浪费以及一些表意不明确的问题。
虚继承具体实现原理:
一个类虚继承另一个类之后,被继承的类就叫做虚拟基类。
当使用虚继承之后,继承便不再是将父类的所有属性全盘继承下来,而是会分为一下的两部分:
- 一部分是虚拟基类的属性部分,该部分存储的是虚拟基类的成员属性
- 另一部分是一个名为vbptr的虚拟基类指针,该指针的作用是通过相应的偏移量计算来找到相应的虚拟基类的位置,并且vbptr是能够被其子类给继承的
- vbptr通过该类的虚拟基类表vbtable通过偏移量的方式找到虚拟基类的位置
使用visual studio 中的开发者命令行工具可以显示类的结构
例如使用非虚拟继承的一个菱形继承案例如下:
#include<iostream>
using namespace std;
class GrandFather
{
public :
int a;
};
class Father1 : public GrandFather
{
};
class Father2 : public GrandFather
{
};
class Son :public Father1,public Father2
{
};
打开开发者工具,转到相应源文件目录。输入cl /d1 reportSingleClassLayout查看的类名 所属文件名
但是虚拟继承后:
#include<iostream>
using namespace std;
class GrandFather
{
public :
int a;
};
class Father1 : virtual public GrandFather
{
public:
int b;
int c;
};
class Father2 :virtual public GrandFather
{
};
class Son :public Father1,public Father2
{
};
虚拟继承后,
虚拟基类只会有一个副本,所以只有一个a(这就是解决菱形继承问题的根本)
总结:
- 虚拟继承不仅是继承父类内容,还会获得一个虚拟基类指针,用于在虚拟基类表中找到虚拟基类的位置
- 虚拟基类指针是能够会被子类继承的
- 一个类中同一个虚拟基类只会存在一个副本,不会存在多个副本