多重继承下的菱形继承
cpp
, 中关于继承的一点问题...
单继承
- 只有一父类的时候,称之为单继承
多继承
- 一个子类有两个及以上的父类,这个时候,称之为多继承
菱形继承
- 多继承下面的特殊状态, 会产生一些问题。
- 当一个类的父类们同时拥有相同的父类的时候,就会发生二义性
问题
1 二义性
解决访问的二义性相对简单,可以通过添加类的限定从而访问到具体的数据
1
2
3
4
5
6
7
8
9
10class Author :public Student, public Teacher
{
public:
Author()
{
Student::name_ = "";
Teacher::name_ = "";
}
};
2 数据冗余
- 从上面的图来看,菱形继承的数据发生了冗余,以及带来数据访问时候的二义性
- 在
Author
中存在两份Person
的数据
- 在
- 数据冗余的问题在
CPP
中通过使用虚继承解决
1 | class Person |
虚继承的实现原理
virtual base table pointer
virtual table
我们基于上面部分分析关于虚继承的实现的原理
VS
的class
布局查看工具- 上述信息包含: 虚函数表及布局,类的大小,类成员占用大小,成员相较于起始地址的偏移量,字节对其信息
上述布局中我们可以看到,当虚继承发生,就会在虚基类的直接子类中产生一个
vbptr
指针,这个指针指向一个虚基类表,Author
继承自Teacher&Student
,同样继承了虚基类指针,同时Author
只存在一份Person
的数据.我们通过虚基类表中记录的偏移(虚基类到当前类),就可以访问到虚基类的数据成员.