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了。這也是虛基表指針實現虛繼承的原理。

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