虚继承场景下的C++对象模型

菱形继承

我们先来回忆一下C++中的菱形继承
菱形继承的概念:

  • 两个派生类继承同一个基类
  • 又有某个类同时继承两个派生类
  • 这种继承被称为菱形继承,或钻石继承

在这里插入图片描述

菱形继承的问题:

  • 羊继承了动物的数据,驼同样继承了动物的数据,当草泥马使用数据时,就会产生二义性
  • 草泥马继承自动物的数据继承了两份,其实我们只需要一份就可以了

解决方法:

  • 当菱形继承,两个父类拥有相同的数据,需要加以作用域区分
  • 利用虚继承,解决菱形继承的问题

虚继承的对象模型

普通继承是子类拷贝并修改父类的虚函数表;虚继承是子类和父类的虚函数表分开保存,将指向父类的虚函数表的指针也加入到子类的对象模型中。
假定单一虚继承场景如下
例如:
在这里插入图片描述
此时派生类Derived的对象模型为:
在这里插入图片描述
可以看到:

  • 派生类的虚函数表和基类的虚函数表是分开的,派生类重写的虚函数将覆盖基类虚函数表中的同名函数。
  • 派生类中新增了一个虚基类指针,它指向一个表,表中保存对象模型中各个虚函数表指针的偏移量,第一项为派生类虚函数表指针的偏移量,第二项为虚继承中第一个基类的虚函数表指针的偏移量,以此类推。
  • 派生类的信息与基类的信息用0x00000000隔开。

使用虚继承的菱形继承:
在这里插入图片描述
结合多重继承与单一虚继承,推导派生类Derived的对象模型为:
在这里插入图片描述
多重继承的布局基本不变,虚基类的信息被追加到内存布局最后,并用0x00000000隔开。此时再访问B::b不会出现二义性。
推导时,从子类往祖父类逐步推进,子类与父类适用多重继承,父类与祖父类适用单一虚继承,每一步只决定派生类的数据成员的位置,例如B::b的布局应该由单一虚继承决定,如果在多重继承时决定,那推出来也是二义的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值