欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

一.什么是繼承?

繼承是類和類之間的關(guān)系,是代碼復(fù)用的重要手段,允許在保持原有類結(jié)構(gòu)的基礎(chǔ)上進(jìn)行擴(kuò)展,創(chuàng)建的新類與原有的類類似,只是多了幾個(gè)成員變量和成員函數(shù)。

二.繼承的方式

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

繼承的方式有以下三種:

在這里插入圖片描述

需要注意的是:

1.若不表明是以何種方式繼承,使用關(guān)鍵字class時(shí)默認(rèn)是私有繼承,使用struct關(guān)鍵字時(shí)默認(rèn)公有繼承

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

三.基類和派生類對(duì)象賦值轉(zhuǎn)換

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

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

構(gòu)造函數(shù)

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

(2)如果基類沒有默認(rèn)的構(gòu)造函數(shù)而是自己寫的構(gòu)造函數(shù),則必須在派生類的構(gòu)造函數(shù)初始化列表階段顯 示調(diào)用,如果基類用的是默認(rèn)構(gòu)造函數(shù),編譯器會(huì)自動(dòng)調(diào)用。

拷貝構(gòu)造

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

(2)默認(rèn)拷貝構(gòu)造會(huì)自動(dòng)調(diào)用父類的拷貝構(gòu)造。顯式定義子類的拷貝構(gòu)造,編譯器默認(rèn)調(diào)用的父類構(gòu)造函數(shù)

賦值運(yùn)算符重載

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

(2)默認(rèn)生成的賦值運(yùn)算符會(huì)自動(dòng)調(diào)用父類的賦值運(yùn)算符顯式定義子類的賦值運(yùn)算符, 編譯器不會(huì)自動(dòng)調(diào)用父類的賦值運(yùn)算符

析構(gòu)函數(shù)

(1)派生類的析構(gòu)函數(shù)會(huì)在被調(diào)用完成后自動(dòng)調(diào)用基類的析構(gòu)函數(shù)清理基類成員。派生類對(duì)象析構(gòu)清理先調(diào)用派生類的析構(gòu)再調(diào)用基類的析構(gòu)

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

(3)父類析構(gòu)在任何情況下編譯器都會(huì)自動(dòng)調(diào)用,不需要顯式調(diào)用

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

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

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

在這里插入圖片描述

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

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

六.繼承性

1.友元關(guān)系不能繼承,基類友元不能訪問子類私有和保護(hù)成員

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

七.菱形繼承

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

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

菱形繼承:兩個(gè)子類同時(shí)繼承一個(gè)父類,而又有子類同時(shí)繼承這兩個(gè)子類

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

解決方法:

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

虛擬繼承

一般不會(huì)實(shí)現(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í),首先需要調(diào)用構(gòu)造函數(shù)。從上圖中看到,在構(gòu)造對(duì)象期間,編譯器給對(duì)象的前4個(gè)字節(jié)填充了數(shù)據(jù)。

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

因此可以推斷應(yīng)該是編譯器默認(rèn)的構(gòu)造函數(shù)所進(jìn)行的操作。

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

在這里插入圖片描述

從反匯編中可以看對(duì)象時(shí)怎樣賦值的。以給_b賦值為例

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

在這里插入圖片描述

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

而個(gè)子類自己的_d賦值時(shí)一條賦值語句就解決了,而在給基類的成員賦值時(shí)通過三條語句來進(jìn)行的。

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

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;//輸出結(jié)果為24
	system("pause");
	return 0;
}

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

在這里插入圖片描述

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

相關(guān)文章

  • Windows下VScode實(shí)現(xiàn)簡單回聲服務(wù)的方法

    Windows下VScode實(shí)現(xiàn)簡單回聲服務(wù)的方法

    回聲服務(wù)端可以將客戶端傳來的信息,再原封不動(dòng)地發(fā)送給客戶端,因而得名 epoch 服務(wù)。接下來通過本文給大家介紹Windows下VScode實(shí)現(xiàn)簡單回聲服務(wù)的方法,感興趣的朋友一起看看吧
    2021-08-08
  • ???????C語言實(shí)現(xiàn)單鏈表基本操作方法

    ???????C語言實(shí)現(xiàn)單鏈表基本操作方法

    這篇文章主要介紹了???????C語言實(shí)現(xiàn)單鏈表基本操作方法,文章圍繞主題展開詳細(xì)介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-05-05
  • 使用Qt實(shí)現(xiàn)監(jiān)聽網(wǎng)頁是否響應(yīng)并導(dǎo)出Excel表

    使用Qt實(shí)現(xiàn)監(jiān)聽網(wǎng)頁是否響應(yīng)并導(dǎo)出Excel表

    Qt導(dǎo)出數(shù)據(jù)到excel,方法有很多,下面這篇文章主要給大家介紹了關(guān)于使用Qt實(shí)現(xiàn)監(jiān)聽網(wǎng)頁是否響應(yīng)并導(dǎo)出Excel表的相關(guān)資料,文中通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • 詳解C++設(shè)計(jì)模式編程中責(zé)任鏈模式的應(yīng)用

    詳解C++設(shè)計(jì)模式編程中責(zé)任鏈模式的應(yīng)用

    這篇文章主要介紹了C++設(shè)計(jì)模式編程中責(zé)任鏈模式的應(yīng)用,責(zé)任鏈模式使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系,需要的朋友可以參考下
    2016-03-03
  • 詳解C++的String類的字符串分割實(shí)現(xiàn)

    詳解C++的String類的字符串分割實(shí)現(xiàn)

    這篇文章主要介紹了詳解C++的String類的字符串分割實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • C語言實(shí)現(xiàn)經(jīng)典掃雷游戲流程

    C語言實(shí)現(xiàn)經(jīng)典掃雷游戲流程

    掃雷是電腦上很經(jīng)典的游戲,特意去網(wǎng)上玩了一會(huì),幾次調(diào)試之后,發(fā)現(xiàn)這個(gè)比三子棋要復(fù)雜一些,尤其是空白展開算法上和堵截玩家有的一拼,與實(shí)際游戲差別較大,不能使用光標(biāo),下面來詳解每一步分析
    2021-11-11
  • C/C++中獲取重載函數(shù)地址的方法

    C/C++中獲取重載函數(shù)地址的方法

    函數(shù)重載是函數(shù)的一種特殊情況,C++允許在同一作用域中聲明幾個(gè)功能類似的同名函數(shù),這 些同名函數(shù)的形參列表不同,常用來處理實(shí)現(xiàn)功能類似數(shù)據(jù)類型不同的問題,本文給大家介紹了C/C++中獲取重載函數(shù)地址的方法,需要的朋友可以參考下
    2024-04-04
  • 一文讓你徹底明白C++中的const

    一文讓你徹底明白C++中的const

    這篇文章主要給大家介紹了關(guān)于C++中const的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • C++基本組件之內(nèi)存池詳解

    C++基本組件之內(nèi)存池詳解

    這篇文章主要為大家詳細(xì)介紹了C++中的基本組件——內(nèi)存池的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C++有一定的幫助,需要的可以參考一下
    2023-03-03
  • 如何獲取C++類成員虛函數(shù)地址的示例代碼

    如何獲取C++類成員虛函數(shù)地址的示例代碼

    這篇文章主要給大家介紹了關(guān)于C++如何獲取類成員虛函數(shù)地址的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08

最新評(píng)論