c++虛繼承復習

深入理解C++虛繼承:解決菱形繼承問題的利器

在C++面向對象編程中,多重繼承是一個強大但容易誤用的特性。今天我們來探討一個特殊的多重繼承形式——虛繼承(Virtual Inheritance),它是解決著名的"菱形繼承問題"的關鍵技術。

什么是菱形繼承問題?

想象這樣一個繼承結構:

class Animal {
public:int age;
};class Mammal : public Animal {};
class Bird : public Animal {};class Platypus : public Mammal, public Bird {};  // 鴨嘴獸既是哺乳動物又是鳥類

這種情況下,Platypus對象將包含兩個Animal子對象(分別來自MammalBird),這會導致:

  1. 存儲空間浪費
  2. 訪問age成員時的二義性
  3. 邏輯上不合理(鴨嘴獸應該只有一個年齡)

虛繼承如何解決這個問題?

使用virtual關鍵字聲明繼承關系:

class Animal {
public:int age;
};class Mammal : virtual public Animal {};  // 虛繼承
class Bird : virtual public Animal {};    // 虛繼承class Platypus : public Mammal, public Bird {};

現在:

  • Platypus對象只包含一個Animal子對象
  • 可以無歧義地訪問age成員
  • 更符合現實世界的邏輯

虛繼承的實現原理

虛繼承的實現通常基于以下機制:

  1. 虛基類表:派生類包含指向共享基類的指針
  2. 共享實例:虛基類在最終派生類中只實例化一次
  3. 間接訪問:通過指針訪問虛基類成員

內存布局簡化表示:

Platypus對象:
+----------------+
| Mammal部分      |
|   vptr_Mammal  | --> 虛基類表
+----------------+
| Bird部分        |
|   vptr_Bird    | --> 虛基類表
+----------------+
| Animal部分      |
|   age          |
+----------------+

虛繼承的特殊初始化規則

虛基類由最底層的派生類直接初始化:

class Animal {
public:Animal(int a) : age(a) {}int age;
};class Mammal : virtual public Animal {
public:Mammal() : Animal(1) {}  // 如果Platypus不初始化Animal,則使用此默認值
};class Bird : virtual public Animal {
public:Bird() : Animal(2) {}     // 如果Platypus不初始化Animal,則使用此默認值
};class Platypus : public Mammal, public Bird {
public:Platypus() : Animal(3), Mammal(), Bird() {}  // 必須直接初始化Animal
};

何時使用虛繼承?

虛繼承適用于:

  1. 經典的菱形繼承結構
  2. 多個接口繼承自同一個基接口
  3. 需要在不同繼承分支間共享基類狀態

注意事項

  1. 性能影響:虛繼承會增加內存開銷和訪問間接性
  2. 初始化責任:最終派生類必須負責虛基類初始化
  3. 設計復雜度:增加類關系的復雜性
  4. 避免濫用:只在真正需要共享基類時使用

總結

虛繼承是C++解決多重繼承中基類共享問題的有效工具,正確使用可以:

  • 消除數據冗余
  • 解決成員訪問二義性
  • 建立更合理的類層次結構

但也需要注意其帶來的復雜性和性能影響。在實際開發中,應當謹慎評估是否真的需要多重繼承和虛繼承,有時候組合模式可能是更好的選擇。

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

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

相關文章

魔樂社區國產算力應用創新大賽重磅開啟!

當國產算力崛起成為 AI 發展新引擎,你是否渴望用創新方案解鎖無限可能?魔樂社區國產算力應用創新大賽重磅來襲!聚焦國產算力前沿,無論你是開發者、研究者,還是技術愛好者,都能在這里一展身手。 現在報名參…

WebView 性能調試與優化全流程:加載速度與渲染性能雙提升

移動端 WebView 頁面通常用于承載復雜的前端應用,尤其是動態加載大量數據或進行高頻率交互時,性能問題尤為突出。用戶常常會遇到頁面加載緩慢、滾動卡頓、甚至是部分內容顯示不完全的情況。在這種情況下,如何優化數據加載與渲染過程&#xff…

51c嵌入式~CAN~合集2

我自己的原文哦~ https://blog.51cto.com/whaosoft/14016935 一、CAN總線常見信號干擾問題 定位干擾原因 當總線有干擾時,有經驗的工程師能夠迅速定位,但是對于新手來說卻很麻煩。 造成總線干擾的原因有很多,比如通過電磁輻射耦合到通…

【cursor實戰】分析python下并行、串行計算性能

提示語 寫一個Python并行計算、串行計算性能對比的代碼。并行計算要包括多線程和多進程兩種,計算的內容要比較復雜 模型 claude-4-sonnet 生成的代碼 #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Python并行計算與串行計算性能對比程序 包含串行…

ubuntu中53端口被占用導致dnsmasq無法使用。已解決。

方案一:修改參數,但不影響使用 編輯配置文件 vim /etc/systemd/resolved.conf將此參數修改為: DNSStubListenerno重啟服務 sudo systemctl daemon-reload sudo systemctl disable systemd-resolved.service方案一:直接禁用 編…

【多模態大模型】訓練與推理直觀解讀

1.直觀案例解讀-圖文問答 假設我們的輸入是一張包含小貓的圖片,以及一個文本提問:“其中是否有小貓?”。下面我將以最詳盡的方式,描述數據在nanoVLM模型中從輸入到輸出的完整流動過程,并解釋每一步中數據的形狀和含義…

uni-app項目實戰筆記17--獲取系統信息getSystemInfo狀態欄和膠囊按鈕

接著上一篇筆記,在添加頭部導航欄后,H5顯示正常: 但在微信小程序中,由于劉海屏的存在,添加的頭部導航欄跟狀態欄重疊在一起: 因此需要獲取狀態欄的高度以便狀態欄和導航欄錯開不重疊在一起。同時頭部導航欄…

Windows下Zookeeper客戶端啟動緩慢問題分析與解決方案

文章目錄 1. 問題描述2. 問題分析2.1 性能分析2.2 根本原因 3. 解決方案3.1 臨時解決方案3.2 長期解決方案 4. 注意事項5. 結論 1. 問題描述 在Windows 8.1 64-bit操作系統環境下,使用Curator框架連接Zookeeper時出現客戶端啟動異常緩慢的問題。具體表現為&#xf…

在 Java 中生成 PDF 縮略圖(教程)

Java 本身無法自動生成 PDF 頁面縮略圖,但幸運的是,有許多軟件庫可以實現這一功能。本文示例使用我們自家的 JPedal 庫,僅需幾行 Java 代碼即可創建縮略圖。JPedal 是開發者使用的最佳 Java PDF 庫。 如何使用 JPedal 將 PDF 轉換為縮略圖 …

基于大模型的甲狀腺結節預測及綜合診療技術方案大綱

目錄 一、技術方案概述二、術前預測與方案制定2.1 結節特征分析與良惡性預測2.2 手術方案建議2.3 麻醉方案優化三、術中輔助決策3.1 實時數據監測與分析3.2 麻醉深度監控與調節四、術后護理與并發癥預測4.1 術后恢復預測4.2 并發癥風險預警五、統計分析與技術驗證5.1 數據分割與…

SpringCloud系列(36)--SpringCloud Gateway簡介

1、SpringCloud GateWay概述 SpringCloud Gateway是 Spring Cloud的一個全新項目,基于Spring 5.0Spring Boot 2.0和Project Reactor等技術開發的網關,它旨在為微服務架構提供一種簡單有效的統—的API路由管理方式;SpringCloud Gateway作為Sp…

TensorFlow深度學習實戰:構建神經網絡全指南

引言:深度學習與TensorFlow概覽 深度學習作為機器學習的一個重要分支,近年來在計算機視覺、自然語言處理、語音識別等領域取得了突破性進展。TensorFlow是由Google Brain團隊開發的開源深度學習框架,自2015年發布以來,已成為最受…

K8S: etcdserver: too many requests

Kubernetes etcdserver: too many requests 錯誤解決方案 當Kubernetes集群出現 etcdserver: too many requests 錯誤時,表明etcd數據庫接收到的請求量超過了其處理能力。etcd作為Kubernetes的核心組件,存儲著集群的所有狀態數據,處理請求過…

銀河麒麟高級服務器操作系統(全架構)OpenGauss 數據庫部署手冊

一、部署前準備工作 1. 環境檢查 項目配置描述內存功能調試建議 32GB 以上。性能測試和商業部署時,單實例部署建議 128GB 以上。復雜的查詢對內存的需求量比較高,在高并發場景下,可能出現內存不足。此時建議使用大內存的機器,或…

Boosting:從理論到實踐——集成學習中的偏差征服者

核心定位:一種通過串行訓練弱學習器、自適應調整數據權重,將多個弱模型組合成強模型的集成學習框架,專注于降低預測偏差。 本文由「大千AI助手」原創發布,專注用真話講AI,回歸技術本質。拒絕神話或妖魔化。搜索「大千A…

Ubuntu下交叉編譯工業相機庫aravis到OpenHarmony(aarch64)使用

文章目錄 下載交叉編譯工具鏈安裝meson編寫交叉編譯配置文件編譯glib編譯libiconv編譯libxml2編譯libusb(暫時不編譯,依賴的udev庫我找不到)編譯Aravis使用 自行編譯的庫都統一放到一個地方去,這樣引用時方便一些,比如…

深入理解互斥信號量(Mutex)在 FreeRTOS 中的使用與實現

在多任務操作系統中,任務間的同步和資源共享是至關重要的。為了避免多個任務同時訪問共享資源,導致資源沖突和數據不一致,信號量(Semaphore) 是常用的同步機制。特別是在 FreeRTOS 中,互斥信號量&#xff0…

Liunx操作系統筆記2

Linux下的包/源管理命令:主要任務是完成在Linux環境下安裝軟件。 1.rpm 是最基礎的rpm包的安裝命令,需要提前下載相關安裝包和依賴包。 2.yum/dnf是基于rpm包的自動安裝命令,可以自動在倉庫中匹配安裝軟件和依賴包。 3.光盤源 是指的 安裝系統…

企業級RAG系統架構設計與實現指南(Java技術棧)

企業級RAG系統架構設計與實現指南(Java技術棧) 開篇:RAG系統的基本概念與企業應用價值 在當今快速發展的AI技術背景下,檢索增強生成(Retrieval-Augmented Generation, RAG) 已成為構建智能問答、知識庫管…

【Rust http編程】Rust搭建webserver的底層原理與應用實戰

?? 歡迎大家來到景天科技苑?? 🎈🎈 養成好習慣,先贊后看哦~🎈🎈 🏆 作者簡介:景天科技苑 🏆《頭銜》:大廠架構師,華為云開發者社區專家博主,…