【C++學習筆記】----詳解菱形繼承(虛擬繼承)

1.菱形的相關問題

1.什麼是菱形繼承?
菱形繼承是C++繼承中的多繼承出現的問題。

2.菱形繼承帶來什麼問題,如何解決?
帶來數據二義性,和數據冗餘問題。
二義性可以通過作用域限定符,限定所操作的數據對象。
數據冗餘問題,需要通過虛擬繼承來解決。
圖解:
在這裏插入圖片描述
3.什麼是組合,什麼是繼承,適用情況有哪些?
組合和繼承都是面向對象編程代碼複用的方式。

組合是解決has-a的問題,(車有發動機)。
優點:封裝性沒有被破壞,類與類的耦合度低。
缺點:調用的時候是通過對象訪問調用接口,不能直接使用接口。

繼承是解決Is-a的問題,(人,學生,老師)
優點:子類直接繼承父類的接口,創建對象時不用創建父類對象。
缺點:父類與子類的耦合度增加,破壞了封裝性,不利於程序的維護。

2.代碼展示

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class per
{
public:
	int _num1;
	
};

class stu:virtual public per
{
public:
	int _num2;
};

class teach :virtual  public per
{
public:
	int _num3;

};
class ass : public teach,  public stu
{
public:
	int _num4;
};
void test6()
{
	per p;
	p._num1 = 1;
	cout << p._num1 << endl;
	stu s;
	s._num1 = 21, s._num2 = 22;
	cout << s._num1 <<" "<< s._num2 << endl;
	teach t;
	t._num1 = 31, t._num3 = 33;
	cout << t._num1 << " " << t._num3 << endl;
	ass a;
	a._num1 = 41, a._num2 = 42, a._num3 = 43, a._num4 = 44;
	a.stu::_num1 = 411, a.teach::_num1 = 4111;
	cout <<a._num1 << " " << a._num2 << " " << a._num3 << " " << a._num4 << endl;
	cout << t._num1 << " " << t._num3 << endl;
	//printf("%p", *(int*)&a);
}
int main()
{
	test6();
	system("pause");
	return 0;
}

3.結果展示

在這裏插入圖片描述

4.結果分析

在這裏插入圖片描述
通過查看地址的方式,我發現虛擬繼承virtual繼承,子類繼承父類的時候,增加了一個虛基表指針,指向虛基表,虛基表的位置存儲的是00000000,下一個位置存儲的是偏移量,即虛基表指針到數據的位置,結尾一般是00000000,而且它們共用一個虛基表。重複的冗餘的數據,放在數據的末尾。
虛基表在內存中放在數據段,下面通過查看地址發現兩個位置非常近。
在這裏插入圖片描述

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