c++中的虚继承主要是为了解决菱形继承的数据冗余和二义性问题。
在菱形继承体系中,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
对象模型:
虚基表指针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;
};
对象模型:
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;
};
对象模型:
d访问虚基类A中的数组也是通过指针+偏移量访问的,d在发生切片时,会根据指针+偏移量找到虚基类成员,然后进行拼接,完成切片。
虚继承基类,在访问虚基类时通过指针+偏移量访问,相比于直接访问会多一些消耗,但相比于现代CPU的计算速度可以忽略不计,因此虚继承是解决继承体系中数据冗余和二义性的好方法,哪一个类对应的数据存在重复,就可将其设置为虚基类。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧