最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中的繼承方式與菱形繼承解析

 更新時間:2023年08月08日 11:35:23   作者:煙華  
這篇文章主要介紹了C++中的繼承方式與菱形繼承解析,繼承是類和類之間的關系,是代碼復用的重要手段,允許在保持原有類結構的基礎上進行擴展,創(chuàng)建的新類與原有的類類似,只是多了幾個成員變量和成員函數(shù),需要的朋友可以參考下

一.什么是繼承?

繼承是類和類之間的關系,是代碼復用的重要手段,允許在保持原有類結構的基礎上進行擴展,創(chuàng)建的新類與原有的類類似,只是多了幾個成員變量和成員函數(shù)。

二.繼承的方式

class 派生類名 :繼承方式 基類名 {};

繼承的方式有以下三種:

在這里插入圖片描述

需要注意的是:

1.若不表明是以何種方式繼承,使用關鍵字class時默認是私有繼承,使用struct關鍵字時默認公有繼承

2.上面的不可訪問是指派生類對象不管是在類里還是類外都不能不訪問

三.基類和派生類對象賦值轉換

  1. 在public繼承的情況下,派生類對象可以賦值給基類對象或基類指針或基類的引用,因為這里它是把一個派生類的對象看成是一個基類的對象,把派生類多的那一部分進行切片操作。 因此當一個基類的指針指向一個派生類的對象時,該指針只能訪問基類定義的函數(shù)。(多態(tài)與此相反。如果基類的此函數(shù)聲明為virtual類型,那么基類指針指向子類對象,該指針在調用該函數(shù)時會調用子類的函數(shù))
  2. 當父類的對象賦值給派生類的指針時,這是十分危險的,雖然也能通過強制類型轉換來進行賦值,但有可能出現(xiàn)越界的問題。

四.派生類的默認成員函數(shù)

構造函數(shù)

(1)派生類的構造函數(shù)需要調用基類的構造函數(shù)來初始化基類的那一部分成員。

(2)如果基類沒有默認的構造函數(shù)而是自己寫的構造函數(shù),則必須在派生類的構造函數(shù)初始化列表階段顯 示調用,如果基類用的是默認構造函數(shù),編譯器會自動調用。

拷貝構造

(1)派生類的拷貝構造函數(shù)需要調用基類的拷貝構造函數(shù)完成基類的拷貝初始化

(2)默認拷貝構造會自動調用父類的拷貝構造。顯式定義子類的拷貝構造,編譯器默認調用的父類構造函數(shù)

賦值運算符重載

(1)派生類的operator=需要調用基類的operator=完成基類的賦值

(2)默認生成的賦值運算符會自動調用父類的賦值運算符顯式定義子類的賦值運算符, 編譯器不會自動調用父類的賦值運算符

析構函數(shù)

(1)派生類的析構函數(shù)會在被調用完成后自動調用基類的析構函數(shù)清理基類成員。派生類對象析構清理先調用派生類的析構再調用基類的析構

(2)父類與子類析構構成同名隱藏:編譯器底層修改的析構函數(shù)的名字,為了支持多態(tài)

(3)父類析構在任何情況下編譯器都會自動調用,不需要顯式調用

五.同名隱藏(重定義)的問題

"同名隱藏“:在基類和派生類中,如果派生類的函數(shù)和基類的函數(shù)同名,就會有同名隱藏。

如果派生類和基類中有同名成員,子類成員將屏蔽父類對同名函數(shù)的直接訪問。(注意不要與函數(shù)重載混淆)

在這里插入圖片描述

如果發(fā)生同名隱藏,那么通過對象來調用同名函數(shù)時,到底是調用子類還是父類的函數(shù),這個是由指針的類型決定,而不是指針執(zhí)行的對象的類型決定的。

解決同名隱藏問題:通過作用域限定符來訪問 (基類::基類成員)

六.繼承性

1.友元關系不能繼承,基類友元不能訪問子類私有和保護成員

2.父類定義static靜態(tài)成員,則整個繼承體系里面只有一個這樣的成員

七.菱形繼承

在談菱形繼承之前,需要先了解單繼承和多繼承:

  • 單繼承是一個子類只有一個直接父類時稱這個繼承關系是單繼承
  • 一個子類有兩個或兩個以上的直接父類時稱這個繼承關系為多繼承 繼承中子類中成員的排列次序與繼承次序有關 (也就是說先繼承的類,類中成員的地址越靠下)

菱形繼承:兩個子類同時繼承一個父類,而又有子類同時繼承這兩個子類

缺點:導致數(shù)據(jù)冗余和二義性的問題

解決方法:

  1. 對造成二義性的屬性使用域訪問限定符,這樣從本質上并沒有解決二義性
  2. 想要解決二義性和數(shù)據(jù)冗余,這就需要用到虛擬繼承。屬性只會生成一份,要調用它需要使用虛基表指針,虛基表指針指向虛基表,虛基表中存在偏移量,通過偏移量就可以找到共有的那個屬性。

虛擬繼承

一般不會實現(xiàn)虛擬繼承,一般是為了解決菱形繼承中的二義性

class B
{
public:
	int _b;
};
class D : virtual public B//虛擬繼承
{
public:
	int _d;
};
int main()
{
	cout << sizeof(D) << endl;//12
	D d;
	d._b = 1;
	d._d = 2;
	return 0;
}

在這里插入圖片描述

在執(zhí)行這段代碼時,首先需要調用構造函數(shù)。從上圖中看到,在構造對象期間,編譯器給對象的前4個字節(jié)填充了數(shù)據(jù)。

而這一個過程只能在構造函數(shù)期間執(zhí)行。

因此可以推斷應該是編譯器默認的構造函數(shù)所進行的操作。

cout << sizeof(D) << endl;改語句輸出為12,比想象中的多了4個字節(jié)。

在這里插入圖片描述

從反匯編中可以看對象時怎樣賦值的。以給_b賦值為例

  • 第一個mov語句:把對象的前4個字節(jié)的內容獲取
  • 第二個mov語句:我們可以把第一個mov語句中獲取得d對象前4個字節(jié)的內容向下偏移4個字節(jié)里面的內容存到ecx中,具體過成如下圖

在這里插入圖片描述

  • 第三個mov語句:把1賦值到d對象偏移量為8的位置

而個子類自己的_d賦值時一條賦值語句就解決了,而在給基類的成員賦值時通過三條語句來進行的。

看完虛擬繼承,接下來我們把虛擬繼承放到菱形虛擬繼承中來看

class B
{
public:
	int _b;
};
class C :virtual public B
{
public:
	int _c;
};
class D : virtual public B
{
public:
	int _d;
};
class A :public C, public D
{
public:
	int _a;
};
int main()
{
	cout << sizeof(A) << endl;//輸出結果為24
	system("pause");
	return 0;
}

為什么它的大小是24個字節(jié)呢?下面給出它的對象模型如下就明白了

在這里插入圖片描述

到此這篇關于C++中的繼承方式與菱形繼承解析的文章就介紹到這了,更多相關C++中的繼承內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C語言通過棧實現(xiàn)小人走迷宮

    C語言通過棧實現(xiàn)小人走迷宮

    這篇文章主要為大家詳細介紹了C語言通過棧實現(xiàn)小人走迷宮,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C++20中的協(xié)程(Coroutine)的實現(xiàn)

    C++20中的協(xié)程(Coroutine)的實現(xiàn)

    這篇文章主要介紹了C++20中的協(xié)程(Coroutine)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • C++排序算法之冒泡排序解析

    C++排序算法之冒泡排序解析

    這篇文章主要介紹了C++排序算法之冒泡排序解析,從左到右,相鄰兩數(shù)兩兩比較,若下標小的數(shù)大于下標大的數(shù)則交換,將最大的數(shù)放在數(shù)組的最后一位,,再次遍歷數(shù)組,將第二大的數(shù),放在數(shù)組倒數(shù)第二的位置,以此類推,直到數(shù)組有序需要的朋友可以參考下
    2023-10-10
  • C++中的類型查詢之探索typeid和type_info(推薦)

    C++中的類型查詢之探索typeid和type_info(推薦)

    C++ 是一種靜態(tài)類型語言,這意味著每個變量的類型在編譯時就已經(jīng)確定,在這篇技術分享中,我們將探討 C++ 中的 typeid 和 type_info,以及如何使用它們來獲取類型信息,需要的朋友可以參考下
    2024-05-05
  • c語言算術運算符越界問題解決方案

    c語言算術運算符越界問題解決方案

    大量的安全漏洞是由于計算機算術運算的微妙細節(jié)引起的, 具體的C語言, 諸如符號數(shù)和無符號數(shù)之間轉換, 算術運算的越界都會導致不可預知的錯誤和安全漏洞, 具體的案例數(shù)不勝數(shù).
    2012-11-11
  • 使用C語言訪問51單片機中存儲器的核心代碼

    使用C語言訪問51單片機中存儲器的核心代碼

    這篇文章主要介紹了使用C語言訪問51單片機中存儲器的相關知識,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01
  • C++中的Switch 語句詳情

    C++中的Switch 語句詳情

    在日常的開發(fā)當中,我們經(jīng)常會遇到一種情況,我們用一個變量表示狀態(tài)。比如關閉-激活-完成,當我們需要判斷狀態(tài)的時候,就需要羅列if-else語句。今天這篇文章我們就來介紹一下C++ Switch 語句,需要的朋友可以參考一下
    2021-11-11
  • 貪心算法 WOODEN STICKS 實例代碼

    貪心算法 WOODEN STICKS 實例代碼

    貪心算法 WOODEN STICKS 實例代碼,需要的朋友可以參考一下
    2013-05-05
  • 詳解C++ thread用法總結

    詳解C++ thread用法總結

    這篇文章主要介紹了詳解C++ thread用法總結,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-07-07
  • window調用api列出當前所有進程示例

    window調用api列出當前所有進程示例

    這篇文章主要介紹了window調用api列出當前所有進程示例,需要的朋友可以參考下
    2014-04-04

最新評論

吉水县| 济阳县| 招远市| 上林县| 余干县| 太和县| 炉霍县| 金山区| 新化县| 涡阳县| 定边县| 南康市| 温泉县| 锦州市| 北碚区| 西乌珠穆沁旗| 修文县| 公主岭市| 金塔县| 马公市| 珠海市| 高陵县| 大港区| 沂水县| 牟定县| 扎赉特旗| 镇远县| 武强县| 诏安县| 蓬溪县| 桓仁| 新龙县| 大悟县| 广昌县| 襄汾县| 贡山| 竹北市| 广宗县| 汉沽区| 曲松县| 宝丰县|