【C++】菱形繼承、菱形虛擬繼承、繼承與組合

目錄

01.概念

02.虛擬繼承

原理

03.繼承和組合


01.概念

單繼承:

一個子類只有一個父類時,稱這種繼承關系為單繼承。

多繼承:

一個子類同時有兩個及以上的父類時,稱這種繼承關系為多繼承。

菱形繼承:

菱形繼承是多繼承的一種特殊形式。

#include<iostream>
using namespace std;
class Person
{
public:string _name; // 姓名
};
class Student : public Person
{
protected:int _num; //學號
};
class Teacher : public Person
{
protected:int _id; // 職工編號
};
class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修課程
};
void Test()
{// 這樣會有二義性無法明確知道訪問的是哪一個Assistant a;a._name = "peter";// 需要顯示指定訪問哪個父類的成員可以解決二義性問題,但是數據冗余問題無法解決a.Student::_name = "xxx";a.Teacher::_name = "yyy";
}

在上述結構中,類 Assistant?通過類 teacher 和類 student 兩次繼承了類 person,導致 Assistant 具有兩份 person 的副本。這會帶來以下問題:

  1. 內存浪費: Assistant 有兩個 person 的副本。
  2. 二義性:訪問 person 中的成員變量或方法時,編譯器無法確定是通過 teacher?還是 student?繼承的 person

?

02.虛擬繼承

虛擬繼承可以解決菱形繼承的二義性和數據冗余問題,如上面的繼承關系,在student和teacher的繼承person時使用虛擬繼承,即可解決問題。


class Person
{
public:string _name; // 姓名
};
class Student : virtual public Person
{
protected:int _num; //學號
};
class Teacher : virtual public Person
{
protected:int _id; // 職工編號
};
class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修課程
};
void Test()
{Assistant a;a._name = "peter";
}

此時就不存在了對_name訪問不明確的問題,因為虛擬繼承保證在整個繼承層次中只存在一份基類的實例。

原理

我們用一個簡化的菱形繼承體系,再借助內存窗口觀察對象成員的模型。


class A
{
public:int _a;
};
// class B : public A
class B : virtual public A
{
public:int _b;
};
// class C : public A
class C : virtual public A
{
public:int _c;
};
class D : public B, public C
{
public:int _d;
};
int main()
{D d;d.B::_a = 1;d.C::_a = 2;d._b = 3;d._c = 4;d._d = 5;return 0;
}

下面是菱形繼承的內存對象成員模型:這里可以看到數據冗余:

下面是菱形虛擬繼承的內存對象成員模型:

這里可以分析出D對象中將A放到了最下面,這個A同時屬于B和C,那么B和C如何去找到公共的A呢?這里是通過了B和C的兩個指針,指向的一張表。這兩個指針叫虛基表指針,這兩個表叫虛基表。虛基表中存的偏移量。通過偏移量可以找到下面的A。?

03.繼承和組合

繼承是一種“is-a”關系,表示一個類是另一個類的特殊化。通過繼承,子類可以獲得父類的屬性和方法。

特點

  1. 代碼復用:子類繼承了父類的屬性和方法,減少了代碼重復。
  2. 層次結構:形成類的層次結構,表示通用和特定的關系。
  3. 多態性:通過繼承,可以實現多態,即使用父類引用指向子類對象。

組合是一種“has-a”關系,表示一個類包含另一個類作為其成員。組合通常用于表示類之間的部分-整體關系。

特點

  1. 靈活性:組合比繼承更加靈活,可以動態地改變組合對象的行為。
  2. 低耦合度:類之間的耦合度較低,有助于維護和擴展代碼。
  3. 封裝性:通過組合,可以將類的實現細節封裝起來,隱藏復雜性。
class Engine {
public:void start() {cout << "Engine started" << endl;}
};class Car {
private:Engine engine; // Car 包含一個 Engine 對象public:void start() {engine.start(); // 使用 Engine 的方法cout << "Car started" << endl;}
};int main() {Car myCar;myCar.start(); // 組合了 Engine 對象return 0;
}

在這個例子中,Car 包含一個 Engine 對象,因此 Car “擁有” 一個 Engine

繼承 vs 組合

  • 繼承

    • 優點:代碼復用、層次結構、多態性。
    • 缺點:強耦合,子類依賴于父類的實現,修改父類可能會影響到所有子類。
  • 組合

    • 優點:靈活性高,低耦合度,易于維護和擴展。
    • 缺點:可能需要編寫更多的代碼來包裝組合對象的功能。

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

以上就是菱形繼承相關知識的整理了,歡迎在評論區留言,覺得這篇博客對你有幫助的,可以點贊收藏關注支持一波~😉

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

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

相關文章

一文搞懂oracle事務提交以及臟數據落盤的原則

本文基于oracle 19c 做事務提交以及oracle臟數據落盤的相關解讀 第一章 相關進程及組件介紹&#xff1a; 1.LGWR&#xff1a; 重做日志條目在系統全局區域 &#xff08;SGA&#xff09; 的重做日志緩沖區中生成。LGWR 按順序將重做日志條目寫入重做日志文件。如果數據庫具有…

【MySQL精通之路】MySQL的使用(3)-命令行連接

本節介紹使用命令行選項來指定如何為MySQL或mysqldump等客戶端建立到MySQL服務器的連接。 有關使用類似URI的連接字符串或鍵值對建立連接的信息&#xff0c;對于MySQL Shell等客戶端&#xff0c;請參閱“使用類似URI字符串或鍵值配對連接到服務器”。 有關無法連接的其他信息&a…

期望薪資26K,北京瘋狂游戲golang一面

北京瘋狂游戲一面 1、自我介紹 2、財務業務中&#xff0c;你做了哪些設計來保證金額數據的準確性&#xff1f;&#xff08;例如&#xff0c;業務涉及多步驟&#xff0c;某一步出了問題怎么解決&#xff09; 3、如何解決單個業務直接報錯的數據準確性問題 4、分布式場景下&a…

理解Vue 3響應式系統原理

title: 理解Vue 3響應式系統原理 date: 2024/5/28 15:44:47 updated: 2024/5/28 15:44:47 categories: 前端開發 tags: Vue3.xTypeScriptSFC優化Composition-APIRef&Reactive性能提升響應式原理 第一章&#xff1a;Vue 3簡介 1.1 Vue 3概述 Vue 3的誕生背景&#xff1…

怎么把電腦上的文件傳到手機上?可保存文檔的云筆記

在職場中&#xff0c;我們經常需要將電腦上的重要文件、資料傳到手機上&#xff0c;以便隨時查閱和使用。比如&#xff0c;當你在公司完成了一份關鍵報告&#xff0c;但即將外出與客戶溝通&#xff0c;這時如果能將報告傳到手機上&#xff0c;就能在移動中隨時準備應對客戶的咨…

uniapp Androud 離線打包升級APK,覆蓋安裝不更新問題

Android 打包時在assets/data/dcloud_control.xml文件中&#xff0c;如果配置debug"true" syncDebug"true"&#xff0c;則consle打印有效&#xff0c;不然沒有打印數據 <hbuilder debug"true" syncDebug"true"> <apps> …

破解App渠道歸因難題,Xinstall助你實現精準數據追蹤!

在移動互聯網時代&#xff0c;App的推廣和運營面臨著諸多挑戰。其中&#xff0c;渠道歸因問題一直困擾著眾多推廣者。如何準確追蹤用戶來源&#xff0c;分析不同渠道的推廣效果&#xff0c;成為了擺在推廣者面前的一大難題。然而&#xff0c;有了Xinstall的出現&#xff0c;這一…

C++網絡編程——實現一個簡單的echo服務器

在前面講完了服務器從建立套接字、綁定、監聽和提取&#xff0c;以及客戶端的連接&#xff0c;我們已經可以動手實現一個簡單的鏡像服務器。 錯誤處理 在那之前&#xff0c;我們先封裝一個錯誤處理函數 errif 可以定義一個uitl.cpp放里面&#xff0c;需要的地方引用即可 ut…

藍橋杯Web開發【大學組:國賽】2022年真題

1.分一分 如果給你一個數組&#xff0c;你能很快將它分割成指定長度的若干份嗎&#xff1f; 1.1 題目問題 請在 js/index.js 文件中補全函數 splitArray 中的代碼&#xff0c;最終返回按指定長度分割的數組。 具體要求如下&#xff1a; 將待分割的&#xff08;一維&#x…

云WAF如何適應動態變化的網絡安全威脅

云WAF&#xff08;Web Application Firewall&#xff09;是一種專門用于保護Web應用程序的安全系統&#xff0c;它能夠實時監測并分析網絡流量&#xff0c;一旦發現潛在攻擊行為立即進行阻斷&#xff0c;有效防止各類Web應用層攻擊。云WAF的適應性主要體現在以下幾個方面&#…

【Docker故障處理篇】運行容器報錯“docker: failed to register layer...file exists.”解決方法

【Docker故障處理篇】運行容器報錯“docker: failed to register layer...file exists.” 一、Docker環境介紹2.1 本次環境介紹2.2 本次實踐介紹二、故障現象2.1 運行容器消失2.2 重新運行容器報錯三、故障分析四、故障處理4.1 停止 Docker 服務:4.2 備份重要數據4.3 清理沖突…

從了解到掌握 Spark 計算框架(一)Spark 簡介與基礎概念

文章目錄 什么是 Spark&#xff1f;核心特點 Spark 對比 MapReduceSpark 編程模型RDDDataFrameDataset Spark 運行模式Spark 生態 什么是 Spark&#xff1f; Spark 是一個基于內存的分布式計算框架&#xff0c;最初由加州大學伯克利分校的 AMPLab 開發&#xff0c;后來捐贈給了…

go語言基準測試Benchmark 最佳實踐-冒泡排序和快速排序算法基準測試時間復雜度對比

在go語言中Benchmark基準測試( 在后綴為_test.go的文件中&#xff0c;函數原型為 func BenchmarkXxx(b *testing.B) {}的函數 )可以用來幫助我們發現代碼的性能和瓶頸&#xff0c; 其最佳實踐 應該是我們最常用的 冒泡排序和快速排序的測試了&#xff0c;廢話不說&#xff0c;直…

【MySQL精通之路】InnoDB(9)-表和頁壓縮(2)-頁壓縮

目錄 1.支持的平臺 2.頁面壓縮的工作原理 3.啟用頁面壓縮 4.禁用頁面壓縮 5.頁面壓縮-元數據 6.使用頁面壓縮識別表 7.頁面壓縮限制和使用說明 InnoDB支持對駐留在FPT表空間中的表進行頁面級壓縮。 此功能被稱為透明頁面壓縮。通過使用CREATE TABLE或ALTER TABLE指定COM…

項目9-網頁聊天室3(主界面之用戶信息)

1.前端頁面 CSS: 如何讓img里的圖片自適應div&#xff0c;且不變形_img自適應div大小 鋪滿且不變形-CSDN博客 JavaScript/jQuery 如何改變一個img元素的src屬性|極客教程 (geek-docs.com) 2.要求 左上角顯示用戶的昵稱和頭像. 3.后端代碼 3.1 添加攔截器 3.2 注冊攔截器 …

關于C++的類型轉換一篇搞掂

類型轉換 本篇主要探討C11的新出現的類型轉換方式 隱式類型轉換(意義相近的類型可轉換) 顯示類型轉換(意義不相近的類型需強制類型轉換) C為了加強類型轉換的可視性, 引入了四種命名強制類型轉換操作符 但同時也兼容了C語言之前的類型轉換和強制類型轉換, 只是提供了規范的轉…

go升級后 編譯的exe在win7上無法正常運行

D:/Go/src/runtime/sys_windows_amd64.s:65 x75 fpx22fca sp-0x22fc8日 升級到go 1.21后報一堆錯誤&#xff0c;要死了啊 原來是go 1.21不支持win7了&#xff0c;必須把go退回到1.20版本 谷歌發布編程語言 Go 1.21 版本&#xff1a;取消支持微軟 Win7/8 及蘋果 macOS 10.13/10…

pip install pytorch-quantization error

一 報錯信息 最近安裝pytorch-quantization報錯&#xff0c;安裝失敗報錯信息如下&#xff1a; Looking in indexes: https://pypi.org/simple, https://pypi.ngc.nvidia.com Collecting pytorch-quantizationDownloading pytorch-quantization-2.2.1.tar.gz (6.8 kB)Prepari…

Alibaba Cloud Linux 安裝docker

阿里云實例基于 Red Hat 的發行版&#xff08;例如 CentOS 或 Alibaba Cloud Linux&#xff09;。在這種情況下&#xff0c;應該使用 yum 或 dnf 包管理器&#xff0c;而不是 apt。以下是如何在 CentOS 或類似系統上安裝 Docker 的步驟&#xff1a; 1. 更新系統 首先&#xf…

網絡滲透思考

1. windows登錄的明文密碼&#xff0c;存儲過程是怎么樣的&#xff0c;密文存在哪個文件下&#xff0c;該文件是否可以打開&#xff0c;并且查看到密文 windows的明文密碼:是通過LSA&#xff08;Local Security Authority&#xff09;進行存儲加密的 存儲過程:當用戶輸入密碼之…