c++多繼承自我理解

單繼承與多繼承

單繼承:一個子類只一一個直接父類時稱這個繼承關係爲單繼承

多繼承:一個子類有兩個或者兩個以上直接父類時稱這個繼承關係爲多繼承。

菱形繼承:菱形繼承是多繼承的一種特殊情況。兩個子類同時繼承一個父類,又有一個子類繼承這兩個子類。

菱形繼承的問題:從下面的代碼可以看出,菱形繼承有數據冗餘和二義性的問題。

class Person{
public:
	string _name;//姓名
};
class Student :public Person
{
protected:
	int _num;//學號
};
class Teacher: public Person
{
protected:
	int _id;//職工編號
};

class Assistant :public Student, public Teacher
{
protected:
	string _majorCourse;//主修課程
};

void Test()
{
	//這樣會有二義性無法明確知道訪問的是哪一個
	Assistant a;
	//a._name = "peter"; 報錯不知道訪問哪一個

	//需要顯示指定訪問那個父類的成員可以解決二義性問題
	//但是數據冗餘問題無法解決
	a.Student::_name = "xxx";
	a.Student::_name = "yyy";
}

解決菱形繼承的二義性和數據冗餘的問題採用虛擬繼承即在繼承時採用virtual關鍵字。虛擬繼承不用在其他地方去使用.

class A
{
public:
	int _a;
};

class B :virtual public A
{
public:
	int _b;
};

class C :virtual public A
{
public:
	int _c;
};

class D :public B, public C
{
public:
	int _d;
};
int main()
{
	D d;
	d.B::_a = 1;
	d.C::_a = 2;
	d._b = 3;
	d._c = 4;
	d._d = 5;

	return 0;
}

通過以上代碼我們發現:
在這裏插入圖片描述

在這裏插入圖片描述
通過觀察內存發現,虛擬繼承中基類部分在下,子類部分在上與普通繼承是反的
B和C中存在兩個類似於地址的數據,其實是兩個指針,指向一張表。這兩個指針叫虛基表指針,這兩個表叫虛基表。虛基表中存在偏移量,通過偏移量可以找到A。虛基表中第一個存在的是相對於自己的偏移量,第二個是相對於派生類的起始位置的偏移量

普通單繼承與虛擬繼承的區別?
1.普通虛擬繼承比普通的單繼承多了4個字節
2.虛擬繼承中基類部分在下,子類部分在上 與普通繼承是反的
3.編譯器會給派生類生成默認的構造函數-----------------要在對象的前4個字節放數據
4.對象前4個字節中的內容------------>指向一塊內存空間(0,8)

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