单继承:一个子类只有一个父类时称为单继承
多继承:一个子类有两个或者两个以上时这个继承关系为多继承
菱形继承是多继承的一种特殊情况
在继承中子类会继承父类的所有的成员,可以看出菱形继承有数据冗余和二义性的问题。Assistant中会有Person的两份数据。
#include <iostream>
#include <string>
using namespace std;
class Person{
public:
int _age;
};
class Student : public Person{
public:
int _stuid;
};
class Teacher : public Person{
public:
int _sid;
};
class Assistant :public Teacher, public Student{
public:
int sss;
};
void test(){
Assistant a;
cout << "Assistant:" << sizeof(a) << endl;
Student s;
cout << "Student:" << sizeof(s) << endl;
Teacher t;
cout << "Teacher:" << sizeof(t) << endl;
Person p;
cout << "Person:" << sizeof(p) << endl;
}
int main() {
test();
system("pause");
return 0;
}
可以从上面看出来我们的Assistant中的sizeof(Assistant)为20,但是现在我们的Teacher和Student都为8,这样可以看出来Assistant继承出两个Person中的对象。
解决办法:对于菱形继承中解决办法是使用虚继承。继承时使用virtual关键字,就可以保证我们的数据只有一份,不会产生数据的二义性。
#include <iostream>
#include <string>
using namespace std;
class Person{
public:
int _age;
};
class Student :virtual public Person{
public:
int _stuid;
};
class Teacher : virtual public Person{
public:
int _sid;
};
class Assistant :public Teacher, public Student{
public:
int sss;
};
void test(){
Assistant a;
cout << "Assistant:" << sizeof(a) << endl;
Student s;
cout << "Student:" << sizeof(s) << endl;
Teacher t;
cout << "Teacher:" << sizeof(t) << endl;
Person p;
cout << "Person:" << sizeof(p) << endl;
}
int main() {
test();
system("pause");
return 0;
}
产生的结果是:
但是为什么使用虚继承会导致我们的sizeof变大呢?这就跟虚拟继承本质相关。
虚继承的原理
虚拟继承就是在虚拟继承时生成一张虚基表,
使用vs进行调试
可以看出我们的Assistant是在虚继承的上面,Teacher中多出了一个虚基表指针,这个指针指向的就是虚基表虚基表中存放的是偏移量,通过偏移量就可以找到Person。
这样就可以知道为什么sizeof(Assistant)的大小是20了。这也是虚基表指针实现虚继承的原理。