c++继承之虚继承

虚继承

存在的理由

存在即合理

虽然我们相信这句话,但是为什么合理呢?是什么促使它存在的呢?
我们引出一个概念,菱形继承
什么是菱形继承:

class A  //大小为4
{
public:
    int a;
};
class B : public A
{
public:
    int b;
};
class C : public A
{
public:
    int c;
};
class D :public B, public C
{
public:
    int d;
};

我们画出它的类图,会发现是一个菱形
当我们实例化D类,对象是d,并且调用d.a;
那么会出现二义性的问题。
通过引入虚函数,可以解决以下问题:
+ 二义性问题
+ 浪费存储空间

实现原理

  • 每个虚继承的子类都有一个虚基类指针(占用一个指针的存储空间,4字节)和虚基类表(不占用类对象的存储空间)
  • 虚基类依旧会在子类里面存在拷贝,只是仅仅最多存在一份而已,并不是不在子类里面了
  • 当虚继承的子类被当做父类继承时,虚基类指针也会被继承。
  • 实际上,vbptr指的是虚基类表指针(virtual base table pointer),该指针指向了一个虚基类表(virtual table),虚表中记录了虚基类与本类的偏移地址;通过偏移地址,这样就找到了虚基类成员,而虚继承也不用像普通多继承那样维持着公共基类(虚基类)的两份同样的拷贝,节省了存储空间。
  • 我的理解是通过偏移地址,找到虚基类成员,如果两个父类的父类是一个类,类似于B的父类是A,C的父类是A,B,C父类相同,那么我们不需要两份相同的继承。

代码示例

class A
{
public:
    int a;
};
class B :virtual public A
{
public:
    int b;
};
class C :virtual public A
{
public:
    int c;
};
class D :public B, public C
{
public:
    int d;
};

注意virtual的位置。

猜你喜欢

转载自blog.csdn.net/Jamence/article/details/81432904