#include<iostream>
using namespace std;
//菱形继承
struct Person{
int m_age;
};
struct Student :Person{
int m_score;
};
struct Worker : Person{
int m_salary;
};
struct Undergradute :Student, Worker{
int m_grade;
};
int main() {
Undergradute ug;
cout << sizeof(ug) << endl;//20
//ug.m_age=10;//由于二义性,ug不能正常访问m_age
getchar();
return 0;
}
菱形继承带来的问题:
1.造成成员变量冗余(空间占用较多)
2.成员变量具有二义性
ug对象内存分布(占用20 个字节):
通过虚继承解决上述问题(虚继承让Student和Worker共同一个m_age):
#include<iostream>
using namespace std;
//菱形继承→虚继承
struct Person{
int m_age;
};
struct Student :virtual Person{
int m_score;
};
struct Worker : virtual Person{
int m_salary;
};
struct Undergradute :Student, Worker{
int m_grade;
};
int main() {
Undergradute ug;
cout << sizeof(ug) << endl;//24
ug.m_age = 10;//此时可以正常访问,二义性问题解决
getchar();
return 0;
}
在上述虚继承中,Person类称为虚基类
使用虚继承后的内存分布(占用24字节,占用空间多于上面菱形继承的20字节。这是由于虚基类成员变量只有一个,所以这里体现不出虚继承的优势,当成员变量有很多时,内存占用会比菱形继承少):
红色:虚表指针与本类起始的偏移量(一般为0)
绿色:虚基类第一个成员变量与本类起始的偏移量