c++虚继承


c++虚继承

c++中的虚继承主要是为了解决菱形继承的数据冗余和二义性问题。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AKgMtJtE-1672131474445)(C:\Users\19199\Desktop\c++研发\c++(新)]\c++虚继承.assets\image-20221227154838026.png)

在菱形继承体系中,D类实例化的对象内部有2份A的成员,在进行访问时,会出现歧义。

虚继承的对象模型

被虚继承的基类称为虚基类,虚基类的子类除了拥有虚基类的成员变量之外,还额外拥有一个指针,该指针称为虚基类表指针,又叫做虚基表指针

class Base {
public:
	int _x;
	int _y;
	int _z;
};
class Son :virtual public Base {
public:
	char _ch;
};
cout << sizeof(Son) << endl;//20

对象模型:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ww5b1MNu-1672131474446)(C:\Users\19199\Desktop\c++研发\c++(新)]\c++虚继承.assets\image-20221227160156251.png)

虚基表指针vbptr(virtual base table pointer)指向虚基表,虚基表中存放偏移量,派生类访问虚基类中的成员变量是通过虚基表指针+偏移量访问的,例如Son s,s._x=10,s访问虚基类的_x是通过拿到s的最低4个字节的数据(vbptr)+偏移量(8)进行访问的。

虚基类的直接子类或间接子类访问虚基类的成员都是通过虚基表指针+偏移量访问的。

class A{
public:
	int _x;
	int _y;
	int _z;
};
class B :virtual public A {
public:
	int _m;
};
class C :public B {
public:
	int _n;
};

对象模型:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ARuVNF0u-1672131474446)(C:\Users\19199\Desktop\c++研发\c++(新)]\c++虚继承.assets\image-20221227162533330.png)

c要访问虚基类成员_x,_y,_z需要通过vbptr+偏移量访问。

虚继承的原理

虚继承更改了访问基类成员的方式,由直接访问变为指针+偏移量的方式访问,当基类成员较大且存在数据冗余时,可以采用虚继承的方式继承基类,以一根指针的代价减小了空间消耗。

class A{
public:
	int _a[1000];
};
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;
};

对象模型:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Il9YOwEr-1672131474447)(C:\Users\19199\Desktop\c++研发\c++(新)]\c++虚继承.assets\image-20221227164521726.png)

d访问虚基类A中的数组也是通过指针+偏移量访问的,d在发生切片时,会根据指针+偏移量找到虚基类成员,然后进行拼接,完成切片。

虚继承基类,在访问虚基类时通过指针+偏移量访问,相比于直接访问会多一些消耗,但相比于现代CPU的计算速度可以忽略不计,因此虚继承是解决继承体系中数据冗余和二义性的好方法,哪一个类对应的数据存在重复,就可将其设置为虚基类。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WfnWv9xB-1672131474447)(C:\Users\19199\Desktop\c++研发\c++(新)]\c++虚继承.assets\image-20221227165545478.png)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值