c++---菱形继承

单继承:一个子类只有一个父类时称为单继承
在这里插入图片描述
多继承:一个子类有两个或者两个以上时这个继承关系为多继承
在这里插入图片描述

菱形继承是多继承的一种特殊情况
在这里插入图片描述

在继承中子类会继承父类的所有的成员,可以看出菱形继承有数据冗余和二义性的问题。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了。这也是虚基表指针实现虚继承的原理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章