深入理解C++面向對象特性之一 多態

歡迎來到干貨小倉庫,堪比沙漠!!!

從“Hello World”到改變世界,中間隔著千萬次'再試一次'.


1.多態的概念

多態的概念:通俗來說,就是多種形態, 具體點就是去完成某個行為,當不同的對象去完成時會 產生出不同的狀態

例如:在買火車票時,若是普通人買票時,是全價買票;學生買票時,是半價買票;軍人買票時,是優先買票。

2.多態的定義及實現

2.1多態的構成條件

多態是在不同繼承關系的類對象,去調用同一函數,產生不同的行為。比如Student繼承了Person。Person對象買全價票,Student對象買半價票。

示例:

那么在繼承中要構成多態的條件有兩個條件:

1、必須通過基類的指針或引用調用虛函數。

2、被調用的函數必須是虛函數,且派生類必須對基類的虛函數進行重寫。

2.2虛函數

虛函數:即被virtual修飾的類成員函數稱為虛函數。

class Person {
public:virtual void BuyTicket() { cout << "買票-全價" << endl;}
};

2.3虛函數的重寫

條件

①是虛函數

②函數名、返回值和參數類型必須相同

但是有兩個例外:

1.協變(基類和派生類的虛函數返回值類型可以不同),但是要求返回值類型必須是父子關系的指針和引用。

2.派生類的重寫虛函數可以不加 virtual,基類的重寫虛函數必須加上。(建議都加上)

示例:返回值的不同

class A
{ };
class B:public A
{ };class Person
{
public:virtual const A& Buyticket(){cout << "買票全價" << endl;return A();}
};
class Student :public Person
{
public:virtual const B& Buyticket(){cout << "買票半價" << endl;return B();}
};

2.4重載、重寫(覆蓋)和重定義(隱藏)的對比

3.C++ 11 override 和 final 關鍵字

3.1 final

作用:

①修飾虛函數,使該虛函數不能被重寫。

②修飾類,使該類不能被繼承。

示例:

3.2 override

作用:幫助派生類檢查是否對虛函數完成重寫,沒有重寫會報錯。

4.抽象類

在虛函數的后面寫上 =0,則這個函數為 純虛函數。

包含純虛函數的類叫做 抽象類(接口類).

4.1虛函數的重寫(接口繼承)

示例:以下程序的輸出結果是什么?

? A: A->0? ? ?B: B->1? ? C: A->1? ? D: B->0? ? ?E: 編譯出錯 ? ? F: 以上都不正確
class A{public:virtual void func(int val = 1){ std::cout<<"A->"<< val <<std::endl;}virtual void test(){ func();}};class B : public A{public:void func(int val=0){ std::cout<<"B->"<< val <<std::endl; }};int main(){B*p = new B;p->test();return 0;}

正確答案:B

解析:構成虛函數的重寫,調用的是B對象對重寫的虛函數,但是 虛函數重寫的是實現,參數都是基類的那部分(接口繼承)。
變形:
答案:D

4.2內聯函數、靜態成員函數和構造函數是否可以是虛函數?

5.多態的底層原理

5.1虛函數表

示例:以下 sizeof(Base) 是多少?


class Base
{
public:virtual void Func1(){cout << "Func1()" << endl;}
private:int _b = 1;
};

解析:通過編譯得到 sizeof(Base) 占 8個字節,多存了一個指針(指向虛函數表)。

注意:對基類的虛函數進行了重寫,其對應的虛函數表指針指向的地址也會發生變化。

1、基類b對象和派生類d對象虛表是不一樣的,這里我們發現Func1完成了重寫,所以d的虛表中存的是重寫的Derive::Func1,所以虛函數的重寫也叫作覆蓋,覆蓋就是指虛表中虛函數的覆蓋。重寫是語法的叫法,覆蓋是原理層的叫法。

示例:

2、虛函數表本質是一個存虛函數指針的指針數組,一般情況這個數組最后面放了一個nullptr。

3、總結一下派生類的虛表生成:

a.先將基類中的虛表內容拷貝一份到派生類虛表中。

b.如果派生類重寫了基類中某個虛函數,用派生類自己的虛函數覆蓋虛表中基類的虛函數。

c.派生類自己新增加的虛函數按其在派生類中的聲明次序增加到派生類虛表的最后。

示例:

4、派生類對基類的虛函數重寫了,故派生類產生的對象,共用一份虛表

示例:

5.2虛函數表,存在哪里?

對比驗證法:根據多態的存儲模型,該對象的前面四個字節存放的是虛表的地址,分別與棧、靜態區、堆、常量區對比。

5.3動態綁定與靜態綁定

1. 靜態綁定又稱為前期綁定(早綁定)在程序編譯期間確定了程序的行為也稱為靜態多態,如:函數重載

2. 動態綁定又稱后期綁定(晚綁定),是在程序運行期間,根據具體拿到的類型確定程序的具體行為,調用具體的函數,也稱為動態多態

6.多繼承的多態

6.1多繼承的虛函數表

觀察下圖可以看出:多繼承派生類的為重寫的虛函數放在第一個繼承基類部分的虛函數表中

為什么重寫func1(),Base1 和 Base2 的虛表中的地址不一樣,但結果一樣?

需要從底層的匯編進行深入刨析,根據其會變得調用,分析得到 編譯器做了處理,目的是為了修改 this 指針。

6.2菱形虛擬繼承的多態


覺得不錯的可以點贊+收藏咯!!!

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

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

相關文章

藍橋備賽指南(14):樹的直徑與重心

樹的直徑 什么是樹的直徑&#xff1f;樹的直徑是樹上最長的一條鏈&#xff0c;當然這條鏈并不唯一&#xff0c;所以一棵樹可能有多條直徑。直徑由兩個頂點u、v來決定&#xff0c;若由一條直徑&#xff08;u,v)&#xff0c;則滿足一下性質&#xff1a; 1&#xff09;u、v的度數…

AIDD-人工智能藥物設計-網絡藥理學-多組學與網絡藥理學分析揭示龜齡集治療少精癥的機制

IF6.7|多組學與網絡藥理學分析揭示龜齡集治療少精癥的機制 2024年10月28日&#xff0c;海軍軍醫大學張衛東教授團隊在Phytomedicine&#xff08;IF6.7&#xff09;上發表了題為“Multi-omics and network pharmacology approaches reveal Gui-Ling-Ji alleviates oligoastheno…

搜狗拼音輸入法純凈優化版:去廣告,更流暢輸入體驗15.2.0.1758

前言 搜狗輸入法電腦版無疑是裝機必備的神器。它打字精準&#xff0c;詞庫豐富全面&#xff0c;功能強大&#xff0c;極大地提升了輸入效率。最新版的搜狗拼音輸入法更是借助AI技術&#xff0c;讓打字變得既準確又高效。而搜狗輸入法的去廣告精簡優化版&#xff0c;通過移除廣…

Franka雙臂機器人:多領域革新與核心技術深度解析

雙臂Franka機器人以類人化操作能力、毫秒級力控響應及智能協同算法為核心&#xff0c;持續推動工業自動化、醫療輔助與農業生產的革新進程。本文深度解析其技術突破與跨行業實踐案例。 Franka雙臂優勢&#xff1a; 高靈活度&#xff1a;7自由度設計&#xff0c;模擬人類手臂運…

Django視圖詳解

前言 歡迎來到我的博客 個人主頁:北嶺敲鍵盤的荒漠貓-CSDN博客 一、Django視圖是什么&#xff1f; 視圖&#xff08;View&#xff09; 是Django處理HTTP請求的核心組件。它接收一個HttpRequest對象&#xff0c;處理業務邏輯&#xff0c;并返回一個HttpResponse對象&#xff08…

【工具變量】上市公安企業社會信任數據集(2004-2023年)

企業社會信任是衡量企業與社會之間信任度的重要指標&#xff0c;反映了企業在公眾眼中的信譽和可靠性。社會信任對企業的持續發展和品牌形象有著至關重要的影響。本分享數據參考張維迎&#xff08;2002年&#xff09;的做法&#xff0c;采用中國企業家調查系統的地區信任調查數…

Python爬取數據(二)

一.example2包下的 1.re模塊的compile函數使用 import repatternre.compile(r\d) print(pattern) 2.match的方法使用 import re patternre.compile(r\d) # m1pattern.match(one123twothree345four) #參數2&#xff1a;指定起始位置(包含),參數3&#xff1a;終止位置(包含),…

spring之Bean的循環依賴問題、反射機制手寫Spring框架、Spring IoC注解式開發

一、Bean的循環依賴問題 1.什么是Bean的循環依賴 A對象中有B屬性。B對象中有A屬性。這就是循環依賴。我依賴你&#xff0c;你也依賴我。 比如&#xff1a;丈夫類Husband&#xff0c;妻子類Wife。Husband中有Wife的引用。Wife中有Husband的引用。 public class Husband {priv…

狀態機的基本使用

狀態機 1. 什么是狀態機 1.1 場景 在業務代碼中對一些業務狀態進行硬編碼&#xff0c;如果有一天更改了業務邏輯就需要更改代碼&#xff0c;不方便進行系統擴展和維護。 if (status 狀態1) {// TODO } else if(status 狀態2) {// TODO } ...另外對訂單狀態的管理是散落在…

22 | 如何繼續提升 Go 開發技術?

提示&#xff1a; 所有體系課見專欄&#xff1a;Go 項目開發極速入門實戰課&#xff1b;歡迎加入 云原生 AI 實戰營 星球&#xff0c;12 高質量體系課、20 高質量實戰項目助你在 AI 時代建立技術競爭力&#xff08;聚焦于 Go、云原生、AI Infra&#xff09;。 「Go 項目開發極速…

LLM Agents項目推薦:MetaGPT、AutoGen、AgentVerse詳解

這一部分我們將深入介紹三大備受關注的LLM Agents項目&#xff1a;MetaGPT、AutoGen和AgentVerse&#xff0c;包括它們的背景、設計思路、主要功能、技術亮點以及典型應用場景。 1. MetaGPT&#xff1a;讓AI像軟件工程團隊一樣協作 項目背景 MetaGPT由Huang et al.于2023年提…

好數(藍橋杯2024省賽B組)

題目描述 一個整數如果按從低位到高位的順序&#xff0c;奇數位&#xff08;個位、百位、萬位……&#xff09;上的數字是奇數&#xff0c;偶數位&#xff08;十位、千位、十萬位……&#xff09;上的數字是偶數&#xff0c;我們就稱之為“好數”。 給定一個正整數 N&#xf…

STM32單片機入門學習——第26節: [9-2] USART串口外設

寫這個文章是用來學習的,記錄一下我的學習過程。希望我能一直堅持下去,我只是一個小白,只是想好好學習,我知道這會很難&#xff0c;但我還是想去做&#xff01; 本文寫于&#xff1a;2025.04.08 STM32開發板學習——第26節: [9-2] USART串口外設 前言開發板說明引用解答和科普…

【學Rust寫CAD】31 muldiv255函數(muldiv255.rs,已經取消)

源碼 // Calculates floor(a*b/255 0.5) #[inline] pub fn muldiv255(a: u32, b: u32) -> u32 {// The deriviation for this formula can be// found in "Three Wrongs Make a Right" by Jim Blinn.let tmp a * b 128;(tmp (tmp >> 8)) >> 8 }代…

LLM+js實現大模型對話

代碼運行效果圖&#xff1a;前提是你有一個可用的openai服務&#xff0c;然后用下面一個html頁即可啟動 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthd…

用claude3.7,不到1天寫了一個工具小程序(11個工具6個游戲)

一、功能概覽和本文核心 本次開發&#xff0c;不是1天干擼&#xff0c;而是在下班后或早起搞的&#xff0c;總體加和計算了一下&#xff0c;大概1天的時間&#xff08;12個小時&#xff09;&#xff0c;平常下班都是9點的衰仔&#xff0c;好在還有雙休&#xff0c;謝天謝地。 …

C++實現文件斷點續傳:原理剖析與實戰指南

文件傳輸示意圖 一、斷點續傳的核心價值 1.1 大文件傳輸的痛點分析 網絡閃斷導致重復傳輸&#xff1a;平均重試3-5次。 傳輸進度不可回溯&#xff1a;用戶無法查看歷史進度。 帶寬利用率低下&#xff1a;每次中斷需從頭開始。 1.2 斷點續傳技術優勢 指標傳統傳輸斷點續傳…

升級 SAP S/4 HANA 之 EWM 攻略

目錄 簡介 知識點 數據遷移 簡介 倉庫管理&#xff0c;SAP 升級不管是否啟動 EWM 功能&#xff0c;評估 EWM 是必經之路&#xff0c;不僅是因為 EWM 是 SAP 主推的倉庫解決方案&#xff0c;更是其功能強大而便捷&#xff0c;不管是簡易倉庫、復雜倉庫、立體倉庫、高架倉庫、…

知識表示方法之六:過程表示法(Procedural Representation)

在人工智能的發展史中&#xff0c;關于知識的表示方法曾存在兩種不同的觀點。一種觀點認為知識主要是陳述性的&#xff0c;其表示方法應著重將其靜態特性&#xff0c;即事物的屬性以及事物間的關系表示出來&#xff0c;稱以這種觀點表示知識的方法為陳述式或說明式表示法&#…

綠色供應鏈管理體系認證:開啟企業可持續發展的綠色新篇章

在全球“雙碳”目標驅動下&#xff0c;綠色供應鏈管理已成為企業高質量發展的核心議題。據國際權威機構預測&#xff0c;到2030年&#xff0c;綠色供應鏈相關市場規模將突破萬億美元。在此背景下&#xff0c;綠色供應鏈管理體系認證不僅是企業合規的“通行證”&#xff0c;更是…