1.什么是菱形继承
创造一个类,另外另外两个类将其作为父类继承,然后又出现一个类将这两个类作为父类继承,就叫菱形继承。
Horse和Lv继承Animal的属性,Luo再继承上面两者的属性,这种模型就是菱形继承,那么当Horse和Lv有相同属性而且Luo不能同时继承两个的属性时,Luo的继承方式就要使用到virtual关键字,virtual能够解决菱形继承的问题。
2.代码实现
当不使用virtual关键字时:
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Animal {
public:
int age;
};
class Horse :public Animal {};
class Lv :public Animal {};
class Luo :public Horse,public Lv {};
int main() {
Luo l;
l.Horse::age = 90;
l.Lv::age = 100;
cout << l.Horse::age << endl;
cout << l.Lv::age << endl;
}
这时候的输出结果是90,100。当然并不符合预期,利用cmd查看一下底层
明显看到Luo类是有两个age分别是继承两个父类的age属性,为了达到一个age属性的目的,添加virtual关键字:
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Animal {
public:
int age;
};
class Horse :virtual public Animal {};
class Lv :virtual public Animal {};
class Luo :public Horse,public Lv {};
int main() {
Luo l;
l.Horse::age = 90;
l.Lv::age = 100;
cout << l.Horse::age << endl;
cout << l.Lv::age << endl;
}
这时候的输出结果为100,查看底层:
vbptr(虚基类指针):v:virtual b:baseb:base ptr:pointer
vbtable(虚基类表格)
虚基类指针指向的是虚基类表格,此时Luo类只有一个age属性,虚基类表格存储的是偏移量,Horse存储一个8,Lv储存一个4,加上偏移量之后最终都指向Animal的age,所以第一次将其修改为90,第二次修改为100,由于修改的是同一份数据,结果就显示两个相同的age属性。