虚基类虚基表虚函数表之间的关系

虚基类/虚基表/虚函数表之间的关系

class A
{
public:
	virtual void func()
	{}
public:
	int _a;
};

class B : virtual public A
{
public:
	virtual void func()
	{}

	virtual void func1()
	{}
public:
	int _b;
};

class C : virtual public A
{
public:
	virtual void func()
	{}
public:
	int _c;
};

class D : public B, public C
{
public:
    //如果不重写会报错
 virtual void func()
	{}
public:
	int _d;
};

int main()
{
	D d;
	d.B::_a = 1;
	d.C::_a = 2;
	d._b = 3;
	d._c = 4;
	d._d = 5;

	return 0;
}

补坑:虚基表中的距离A的偏移量没有存在第一个位置,它存在第二个位置,跟这里多多少少有点关系。

如果在腰部(B、C)不使用虚继承,且不重写A类中的func函数,不会有什么问题。

如果在腰部(B、C)不使用虚继承,且B、C重写了A中的func函数,也不会有问题。

因为它们现在就和多继承一样,各自有各自的虚表,子类对象D有一个B,有一个C,B有一个虚表,C有一个虚表,各自玩各自的,反正A有两份,无所谓。

当在腰部使用虚继承后,编译就会报错,为什么?

因为这个时候对象模型已经变成这个样子了:A同时属于B和C,在B、C中各自有一份距离A偏移量的虚基表,解决了数据冗余二义性。

而A中有一个虚函数那就有一份虚表,存的是虚函数地址。但是B、C都重写func函数,B、C是共享一个A,那你说子类D是放B的虚函数还是C的虚函数呢?

这个时候就会出现“D” : “void A::func(void)”的不明确继承的报错。

要处理这个问题只能在D中再重写一下func。我不用你B的也不用你C的了。

image-20221004144944089

还有一个问题,如果我在B/C中增加一个虚函数func1,B继承了A,C继承了A,现在只有同一份A,那B、C的虚函数都往A的虚表里面放吗?

因为A是公共的,所以就不会再放入A的虚表里面了,B会建立自己的虚表。我们通过内存发现B的对象模型中在虚基表的偏移量前面多存了一个指针,这个指针存的是距离自己建立的虚表的指针的偏移量。B/C不仅继承了A的虚表指针,如果自己新增虚函数,自己也会建立虚表.

中在虚基表的偏移量前面多存了一个指针,这个指针存的是距离自己建立的虚表的指针的偏移量。B/C不仅继承了A的虚表指针,如果自己新增虚函数,自己也会建立虚表.

正常的继承我们发现先继承的在前面,而虚拟继承改变了对象模型:a反而在最下面且继承时既没有放在B里面也没有放在C里面,编译器把它放在了公共区域。实际上B/C的对象模型也被改了.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yuucho

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值