菱形继承
菱形继承(Diamond Inheritance)是指一个派生类同时继承自两个直接或间接基类,而这两个基类又共同继承自同一基类的情况。这种继承关系形成了类似于菱形的结构,因此称为菱形继承。
图中,Animal是基类,Mammal和Bird是它的派生类,而Bat则同时从Mammal和Bird派生,形成了菱形继承。
虚基类
当一个类被声明为虚基类时,它的派生类只会保留一个对该虚基类的引用,从而解决了多次继承带来的二义性和冲突问题。
其中,这个被共享的基类就称为虚基类(Virtual Base Class)。派生类的同名成员比虚基类的优先级更高
二义性的解决方法
1.加作用域
例:
class Animal { public: int data; }; class Sheep:public Animal { public: }; class Tuo:public Animal { public: }; class SheepTuo:public Sheep,public Tuo { public: }; int main() { SheepTuo test; //test.data=100;//报错,test中有两个a //解决方式1:加作用域 test.Sheep::data=100; test.Tuo::data=100; return 0; }
深入研究(VS studio)
Animal类
Sheep类
Tuo类
SheepTuo类
2.虚继承
声明:
例:
class Animal { public: int data; }; class Sheep:virtual public Animal { public: }; class Tuo:virtual public Animal { public: }; class SheepTuo:public Sheep,public Tuo { public: }; int main() { SheepTuo test; test.data=100; return 0; }
深入研究(VS studio)
Animal类
Sheep类
vbptr(虚基类指针):v是virtual,b是base,ptr是指针。指向虚基类表
vbtable(虚基类表):保存了当前的虚指针相对于虚基类的首地址的偏移量(即子类中从父类继承的数据相对父类的偏移量)--从此,继承的不再是数据,而是指针和虚基类表
总结:之所以产生vbptr和vbtable目的保证不管多少个继承虚基类的数据只有一份。
Tuo类
SheepTuo类
根据不同的虚基类表,可以定位到相同的数据
1.vbtable@Sheep@:偏移量是8;sheep的指针指向0,偏移8,正好是data
2.vbtable@Tuo@:偏移量是4;sheep的指针指向4,偏移4,正好也是data