【C++】繼承(下)

大家好,我是蘇貝,本篇博客帶大家了解C++的繼承(下),如果你覺得我寫的還不錯的話,可以給我一個贊👍嗎,感謝??
在這里插入圖片描述


目錄

  • 5.繼承與友元
  • 6.繼承與靜態成員
  • 7.復雜的菱形繼承及菱形虛擬繼承
  • 8.繼承的總結和反思
  • 9.筆試面試題

5.繼承與友元

友元關系不能繼承,也就是說基類友元不能訪問子類私有和保護成員,就像父母的朋友不是你的朋友一樣
在這里插入圖片描述

6.繼承與靜態成員

基類定義了static靜態成員,則整個繼承體系里面只有一個這樣的成員。父類靜態成員屬于當前類,也屬于當前類的所有派生類,因此無論派生出多少個子類,都只有一個static成員實例

在這里插入圖片描述
在這里插入圖片描述

如果我們想知道A及其派生類實例化了多少對象,就可以定義一個static變量

在這里插入圖片描述

在這里插入圖片描述

7.復雜的菱形繼承及菱形虛擬繼承

單繼承:一個子類只有一個直接父類時稱這個繼承關系為單繼承

在這里插入圖片描述

多繼承:一個子類有兩個或以上直接父類時稱這個繼承關系為多繼承
在這里插入圖片描述

多繼承的定義如上圖的Assistant,只需要在原本繼承的基礎上加逗號和其它基類即可

菱形繼承:菱形繼承是多繼承的一種特殊情況。比如助教,對老師來說,他是個學生;對學生來說,他是個老師。因此他有學生和老師兩個身份,就繼承了學生類和老師類
在這里插入圖片描述

菱形繼承的問題:從下面的對象成員模型構造,可以看出菱形繼承有數據冗余和二義性(后面介紹)的問題。
在這里插入圖片描述

數據冗余:在Assistant的對象中Person成員會有兩份。
二義性:Student和Teacher類都有_name,無法明確知道訪問的是哪一個

在這里插入圖片描述
在這里插入圖片描述

虛擬繼承可以解決菱形繼承的二義性和數據冗余的問題。如上面的繼承關系,在Student和 Teacher的繼承Person時使用虛擬繼承(在繼承公共的基類時用虛擬繼承),即只保存1份Person的成員,就不會造成數據冗余,二義性也就解決了。需要注意的是,虛擬繼承不要在其他地方去使用。

在這里插入圖片描述
在這里插入圖片描述

在上面這種菱形繼承中,虛擬繼承用在菱形的腰部B和C,那下圖的用在哪呢?也是B和C,virtual放在有公共基類(A)的類中
在這里插入圖片描述

虛擬繼承解決數據冗余和二義性的原理:
為了研究虛擬繼承原理,我們給出了一個簡化的菱形繼承繼承體系,再借助內存窗口觀察對象成員的模型。

下面是不加虛擬繼承的菱形繼承
在這里插入圖片描述

在這里插入圖片描述

我們可以從內存窗口看出,D里面包含2份A的成員,會導致數據冗余和二義性。因為類D先繼承B,再繼承C,因此D類的對象d中,先出現類B的成員,再是類C的成員,最后是類D的成員。
同理,如果類D先繼承C,再繼承B,那么D類的對象d中,先出現類C的成員,再是類B的成員,最后是類D的成員。

下面我們加上虛擬繼承
在這里插入圖片描述
在這里插入圖片描述

我們可以從內存窗口看出,D里面只包含1份A的成員,不會導致數據冗余和二義性。而且這時的B和C類的成員中都不包含本來有的A類成員,并且都存儲了一個地址(0x00677bdc和0x00677be4,機器是小端存儲),我們來看看這2個地址指向的內容

在這里插入圖片描述
在這里插入圖片描述

原來地址指向的空間(叫虛基表)里存放的是與A的成員的偏移量(還有其它的內容,這里不做介紹)

為什么要存偏移量?在切片的時候有用。將d賦值給類B的對象bb,就要把D類中B類那部分切來賦值過去,可是這里的B類的成員不包括A類的成員,因此B類保存的地址就能找到與A類的成員的偏移量,就能找到A類的成員,才能最終將B類的成員賦值給bb

在這里插入圖片描述

多繼承本身沒有問題,但有多繼承就可能導致菱形繼承

總結:實踐中可以設計多繼承,但切記不要設計菱形繼承,因為太復雜,容易出現各種問題

問:下面哪個選項是正確的?
在這里插入圖片描述

A:p1 == p2 == p3
B:p1 < p2 < p3
C:p1 == p3 != p2
D:p1 != p2 != p3

答案:C
在這里插入圖片描述

問:下面哪個選項是正確的?
在這里插入圖片描述

A:p1 == p2 == p3
B:p1 < p2 < p3
C:p2 == p3 != p1
D:p1 != p2 != p3

答案:C
在這里插入圖片描述

問:下面程序的結果是什么?
在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述

類D的對象定義時先走初始化列表,再走函數體,所以”class D”一定在最后。先聲明的先走初始化列表,D類中先聲明的是B類,B繼承A,所以A比B更先聲明,再聲明C,最后D。因此A->B->C->D

8.繼承的總結和反思

1、 很多人說C++語法復雜,其實多繼承就是一個體現。有了多繼承,就存在菱形繼承,有了菱形繼承就有菱形虛擬繼承,底層實現就很復雜。所以一般不建議設計出多繼承,一定不要設計出菱形繼承。否則在復雜度及性能上都有問題。
2、 多繼承可以認為是C++的缺陷之一,很多后來的語言都沒有多繼承,如Java。
3、 繼承和組合
組合是什么?將一個類(如A)作為成員變量放在另一個類中(如B)
在這里插入圖片描述

public繼承是一種is-a的關系。也就是說每個派生類對象都是一個基類對象。組合是一種has-a的關系。假設B組合了A,每個B對象中都有一個A對象。

適合is-a的關系,如人和學生,就用is-a。適合has-a的關系,如汽車和輪胎,就用has-a。is-a和has-a都可以,如鏈表和棧,就用has-a。即優先使用對象組合,而非類繼承

繼承允許你根據基類的實現來定義派生類的實現。這種通過生成派生類的復用通常被稱為白箱復用(white-box reuse)。術語“白箱”是相對可視性而言:在繼承方式中,基類的內部細節對子類可見 。繼承一定程度破壞了基類的封裝,基類的改變,對派生類有很大的影響。派生類和基類間的依賴關系很強,耦合度高。

對象組合是類繼承之外的另一種復用選擇。新的更復雜的功能可以通過組裝或組合對象來獲得。對象組合要求被組合的對象具有良好定義的接口。這種復用風格被稱為黑箱復用(black-box reuse),因為對象的內部細節是不可見的。對象只以“黑箱”的形式出現。組合類之間沒有很強的依賴關系,耦合度低。優先使用對象組合有助于你保持每個類被封裝。

實際盡量多去用組合。組合的耦合度低,代碼維護性好。不過繼承也有用武之地的,有些關系就適合繼承那就用繼承,另外要實現多態,也必須要繼承。類之間的關系可以用繼承,可以用組合,就用組合。

9.筆試面試題

1、 什么是菱形繼承?菱形繼承的問題是什么?
2、 什么是菱形虛擬繼承?如何解決數據冗余和二義性的
3、 繼承和組合的區別?什么時候用繼承?什么時候用組合?

復用的常見體現:
1、 函數邏輯的復用
2、 模板
3、 繼承
4、 組合


好了,那么本篇博客就到此結束了,如果你覺得本篇博客對你有些幫助,可以給個大大的贊👍嗎,感謝看到這里,我們下篇博客見??

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/894531.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/894531.shtml
英文地址,請注明出處:http://en.pswp.cn/news/894531.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

項目開發實踐——基于SpringBoot+Vue3實現的在線考試系統(九)(完結篇)

文章目錄 一、成績查詢模塊實現1、學生成績查詢功能實現1.1 頁面設計1.2 前端頁面實現1.3 后端功能實現2、成績分段查詢功能實現2.1 頁面設計2.2 前端頁面實現2.3 后端功能實現二、試卷練習模塊實現三、我的分數模塊實現1、 頁面設計2、 前端頁面實現3、 后端功能實現四、交流區…

【流媒體】搭建流媒體服務器

搭建Windows Nginx服務器 搭建 下載nginx工具包解壓至本地&#xff0c;并在cmd窗口中切換至nginx所在的本地目錄修改 conf/nginx.conf 文件&#xff0c;更改其端口號 server中的 listen的端口號從 80改為 8080&#xff0c;因為80經常被其他服務占用&#xff0c;導致無法打開 …

攜程Java開發面試題及參考答案 (200道-下)

insert 一行數據的時候加的是什么鎖?為什么? 在 MySQL 中,當執行 INSERT 操作插入一行數據時,加鎖的情況會因存儲引擎和具體的事務隔離級別而有所不同。一般來說,在 InnoDB 存儲引擎下,INSERT 操作加的是行級排他鎖(Row Exclusive Lock),以下詳細說明原因。 行級排他…

洛谷P11655「FAOI-R5」Lovely 139

P11655「FAOI-R5」Lovely 139 題目背景 Update&#xff1a;數據有 0 0&#xff0c;答案為 1&#xff0c;請選手特判以正常通過。 Height ≤ 139 \text{Height}\leq139 Height≤139。 題目描述 對于一個 01 \tt 01 01 串 S S S&#xff08;下標從 1 1 1 開始&#xff09;…

【Linux】24.進程信號(1)

文章目錄 1. 信號入門1.1 進程與信號的相關知識1.2 技術應用角度的信號1.3 注意1.4 信號概念1.5 信號處理常見方式概覽 2. 產生信號2.1 通過終端按鍵產生信號2.2 調用系統函數向進程發信號2.3 由軟件條件產生信號2.4 硬件異常產生信號2.5 信號保存 3. 阻塞信號3.1 信號其他相關…

《手札·開源篇》從開源到商業化:中小企業的低成本數字化轉型路徑 ——以Odoo為數據中臺低成本實現售前售中一體化

某機電設備有限公司數字化轉型案例&#xff1a;以Odoo為數據中臺實現售前售中一體化 一、企業背景某機電設備有限公司在機電設備領域歷經多年發展&#xff0c;業務廣泛&#xff0c;涵蓋工業自動化設備、電力設備等產品的銷售與服務。隨著業務版圖不斷拓展&#xff0c;企業面臨…

筆試-業務邏輯4

應用 小明在玩一個數字加減游戲&#xff0c;輸入4個正整數&#xff1a;s、t、a、b&#xff0c;其中s>1&#xff0c;b<105&#xff0c;a!b。只使用加法或者減法&#xff0c;使得st。 每回合&#xff0c;小明用當前的數字&#xff0c;加上或減去一個數字&#xff1b;目前有…

Windows 中的 WSL:開啟你的 Linux 之旅

今天在安裝windows上安裝Docker Desktop的時候&#xff0c;遇到了WSL。下面咱們就學習下。 歡迎來到濤濤聊AI 一、什么是 WSL&#xff1f; WSL&#xff0c;全稱為 Windows Subsystem for Linux&#xff0c;是微軟為 Windows 系統開發的一個兼容層&#xff0c;它允許用戶在 Win…

編程題-電話號碼的字母組合(中等)

題目&#xff1a; 給定一個僅包含數字 2-9 的字符串&#xff0c;返回所有它能表示的字母組合。答案可以按 任意順序 返回。 給出數字到字母的映射如下&#xff08;與電話按鍵相同&#xff09;。注意 1 不對應任何字母。 解法一&#xff08;哈希表動態添加&#xff09;&#x…

python:如何播放 .spx 聲音文件

.spx 是 Speex音頻編解碼器的文件擴展名&#xff0c;它是一種開源的、免費的音頻編解碼器&#xff0c;主要用于語音壓縮和語音通信領域。spx 文件通常用于語音記錄、VoIP應用、語音信箱等場景。 .mp3 是一種廣泛使用的音頻格式&#xff0c;它采用了有損壓縮算法&#xff0c;可…

數據結構課程設計(三)構建決策樹

3 決策樹 3.1 需求規格說明 【問題描述】 ID3算法是一種貪心算法&#xff0c;用來構造決策樹。ID3算法起源于概念學習系統&#xff08;CLS&#xff09;&#xff0c;以信息熵的下降速度為選取測試屬性的標準&#xff0c;即在每個節點選取還尚未被用來劃分的具有最高信息增益的…

Vue3學習筆記-事件-4

一、事件處理 使用v-on或者后面加事件&#xff1a; <template><button v-on:click"addCount()">{{count}}</button> </template> 二、事件傳參 傳event&#xff1a; 不傳參時&#xff0c;默認自動接收 event 傳自定義參數時&#xff0c…

Node.js下載安裝及環境配置

目錄 一、下載 1. 查看電腦版本&#xff0c;下載對應的安裝包 2. 下載路徑下載 | Node.js 中文網 二、安裝步驟 1. 雙擊安裝包 2. 點擊Next下一步 3. 選擇安裝路徑 4. 這里我選擇默認配置&#xff0c;繼續Next下一步&#xff08;大家按需選擇&#xff09; 5. 最后inst…

k8s二進制集群之ETCD集群證書生成

安裝cfssl工具配置CA證書請求文件創建CA證書創建CA證書策略配置etcd證書請求文件生成etcd證書 繼續上一篇文章《負載均衡器高可用部署》下面介紹一下etcd證書生成配置。其中涉及到的ip地址和證書基本信息請替換成你自己的信息。 安裝cfssl工具 下載cfssl安裝包 https://github…

使用python實現與本地ollama部署的deepseek對話

專欄總目錄 按照ollama官方doc的example操作&#xff0c;沒有成功與本地ollama上的deepseek-r1:1.5b通訊后&#xff0c;發現vscode可以調用本地ollama上的deepseek模型。 為了實現與ollama上的deepseek模型通訊&#xff0c;我使用wireshark對本地回環地址進行偵聽后&#xff0c…

【大模型理論篇】最近大火的DeepSeek-R1初探系列1

1. 背景介紹 這一整個春節&#xff0c;被DeepSeek-R1刷屏。各種鋪天蓋地的新聞以及老板發的相關信息&#xff0c;著實感受到DeepSeek-R1在國外出圈的震撼。 DeepSeek推出了新的推理模型&#xff1a;DeepSeek-R1-Zero 和 DeepSeek-R1。DeepSeek-R1-Zero 是一個在沒有經過監督微調…

C++哈希表深度解析:從原理到實現,全面掌握高效鍵值對存儲

目錄 一、核心組件與原理 1. 哈希函數&#xff08;Hash Function&#xff09; 2. 沖突解決&#xff08;Collision Resolution&#xff09; 3. 負載因子&#xff08;Load Factor&#xff09;與擴容 二、C實現&#xff1a;std::unordered_map 1. 模板參數 2. 關鍵操作與復…

Pandoc, Zotero, JabRef 管理論文引用,生成參考文獻 | 撰寫論文 paper

書接上回&#xff0c;使用 Obsidian, Zotero, JabRef, Pandoc, Markup-Markdown | 撰寫論文 paper 管理論文引用&#xff0c;生成參考文獻 TL; DR導出 bibliography 文件JabRefZotero 參考文獻引用語法reference-docLinks TL; DR 安裝 pandoc v3.6.2. 使用一下命令&#xff0c…

為AI聊天工具添加一個知識系統 之85 詳細設計之26 批流一體式 與數據提取器

Q843、批流一體式 統一數據處理框架 "批流一體式統一數據處理框架" 這一概念通常指的是一種將批處理&#xff08;Batch Processing&#xff09;和流處理&#xff08;Stream Processing&#xff09;結合在一起的數據處理架構。它的目標是提供一個統一的框架&#xff…

深入理解 `box-sizing: border-box;`:CSS 布局的利器

深入理解 box-sizing: border-box;&#xff1a;CSS 布局的利器 默認行為示例代碼 使用 box-sizing: border-box;示例代碼 全局應用 box-sizing: border-box;示例代碼 實際應用場景1. 表單布局2. 網格布局 總結 在 CSS 中&#xff0c;box-sizing 屬性決定了元素的總寬度和高度是…