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

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

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

一.什么是繼承?

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

二.繼承的方式

class 派生類(lèi)名 :繼承方式 基類(lèi)名 {};

繼承的方式有以下三種:

在這里插入圖片描述

需要注意的是:

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

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

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

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

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

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

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

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

拷貝構(gòu)造

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

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

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

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

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

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

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

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

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

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

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

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

在這里插入圖片描述

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

解決同名隱藏問(wèn)題:通過(guò)作用域限定符來(lái)訪問(wèn) (基類(lèi)::基類(lèi)成員)

六.繼承性

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

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

七.菱形繼承

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

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

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

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

解決方法:

  1. 對(duì)造成二義性的屬性使用域訪問(wèn)限定符,這樣從本質(zhì)上并沒(méi)有解決二義性
  2. 想要解決二義性和數(shù)據(jù)冗余,這就需要用到虛擬繼承。屬性只會(huì)生成一份,要調(diào)用它需要使用虛基表指針,虛基表指針指向虛基表,虛基表中存在偏移量,通過(guò)偏移量就可以找到共有的那個(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è)過(guò)程只能在構(gòu)造函數(shù)期間執(zhí)行。

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

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

在這里插入圖片描述

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

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

在這里插入圖片描述

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

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

看完虛擬繼承,接下來(lái)我們把虛擬繼承放到菱形虛擬繼承中來(lái)看

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)文章

  • C語(yǔ)言通過(guò)棧實(shí)現(xiàn)小人走迷宮

    C語(yǔ)言通過(guò)棧實(shí)現(xiàn)小人走迷宮

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

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

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

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

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

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

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

    c語(yǔ)言算術(shù)運(yùn)算符越界問(wèn)題解決方案

    大量的安全漏洞是由于計(jì)算機(jī)算術(shù)運(yùn)算的微妙細(xì)節(jié)引起的, 具體的C語(yǔ)言, 諸如符號(hào)數(shù)和無(wú)符號(hào)數(shù)之間轉(zhuǎn)換, 算術(shù)運(yùn)算的越界都會(huì)導(dǎo)致不可預(yù)知的錯(cuò)誤和安全漏洞, 具體的案例數(shù)不勝數(shù).
    2012-11-11
  • 使用C語(yǔ)言訪問(wèn)51單片機(jī)中存儲(chǔ)器的核心代碼

    使用C語(yǔ)言訪問(wèn)51單片機(jī)中存儲(chǔ)器的核心代碼

    這篇文章主要介紹了使用C語(yǔ)言訪問(wèn)51單片機(jī)中存儲(chǔ)器的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-01-01
  • C++中的Switch 語(yǔ)句詳情

    C++中的Switch 語(yǔ)句詳情

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

    貪心算法 WOODEN STICKS 實(shí)例代碼

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

    詳解C++ thread用法總結(jié)

    這篇文章主要介紹了詳解C++ thread用法總結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • window調(diào)用api列出當(dāng)前所有進(jìn)程示例

    window調(diào)用api列出當(dāng)前所有進(jìn)程示例

    這篇文章主要介紹了window調(diào)用api列出當(dāng)前所有進(jìn)程示例,需要的朋友可以參考下
    2014-04-04

最新評(píng)論

信阳市| 孝义市| 高雄县| 巴彦淖尔市| 蓬溪县| 方山县| 潞西市| 买车| 永吉县| 应城市| 贵定县| 鹤庆县| 澄江县| 海南省| 扶余县| 武强县| 廉江市| 荃湾区| 邳州市| 清镇市| 嘉禾县| 莱芜市| 闽侯县| 梁平县| 楚雄市| 云安县| 双流县| 北碚区| 东莞市| 海口市| 台北市| 惠州市| 托克托县| 杂多县| 大洼县| 理塘县| 和林格尔县| 和静县| 大兴区| 重庆市| 密云县|