0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

詳談C++特性:多態(tài)的概念分類和實(shí)現(xiàn)原理

如意 ? 來源:CSDN ? 作者:cherrydreamsover ? 2020-06-29 12:54 ? 次閱讀

一、多態(tài)的概念

在說多態(tài)之前,我們來先看一看對(duì)象的類型

詳談C++特性:多態(tài)的概念分類和實(shí)現(xiàn)原理

來看一個(gè)例子:

詳談C++特性:多態(tài)的概念分類和實(shí)現(xiàn)原理

多態(tài):意思既是同一個(gè)事物的多種形態(tài),用我們C++的專業(yè)詞語來說就是:一個(gè)借口、多種實(shí)現(xiàn)方式。

二、多態(tài)分類

詳談C++特性:多態(tài)的概念分類和實(shí)現(xiàn)原理

靜態(tài)多態(tài):

靜態(tài)多態(tài):編譯器在編譯期間完成的,編譯器根據(jù)函數(shù)實(shí)參的類型(可能會(huì)進(jìn)行隱式類型轉(zhuǎn)換),可推斷出要調(diào)用那個(gè)函數(shù),如果有對(duì)應(yīng)的函數(shù)就調(diào)用該函數(shù),否則出現(xiàn)編譯錯(cuò)誤。

動(dòng)態(tài)多態(tài):

動(dòng)態(tài)多態(tài)就是我們常說的多態(tài)。動(dòng)態(tài)多態(tài)是在程序運(yùn)行期間才決定調(diào)用哪個(gè)函數(shù),是根據(jù)虛函數(shù)表實(shí)現(xiàn)的。聲明了虛函數(shù)的類,類中都有一張?zhí)摵瘮?shù)表,里面存放類的入口地址。通過賦值兼容規(guī)則,可以用父類的指針或引用找到子類的虛函數(shù)。虛函數(shù)是處理類的派生體系中不同層次上不同作用域的同名問題,因此動(dòng)態(tài)多態(tài)必須在類的繼承體系中才能實(shí)現(xiàn)。

三、多態(tài)的實(shí)現(xiàn)原理(動(dòng)態(tài))

說到這里,有幾個(gè)非常重要的概念,需要我們加以區(qū)分:重載、重寫、重定義

通過上面的多態(tài)的介紹,這里來說幾個(gè)重要的概念:

(1)虛函數(shù)表指針:類中除了定義成員函數(shù)之外還有一個(gè)成員是虛函數(shù)表指針(占四個(gè)基本內(nèi)存單位),這個(gè)指針指向一個(gè)虛函數(shù)表的起始位置,這個(gè)表會(huì)與類的定義同時(shí)出現(xiàn),這個(gè)表會(huì)與類的定義同時(shí)出現(xiàn),這個(gè)表存放著該類的虛函數(shù)指針,調(diào)用的時(shí)候可以找到該類虛函數(shù)表指針,通過虛函數(shù)表指針找到虛函數(shù)表,通過虛函數(shù)表的偏移找到函數(shù)的入口地址,從而找到要使用的虛函數(shù)。

(2)當(dāng)實(shí)例化一個(gè)該類的子類對(duì)象的時(shí)候,(如果)該類的子類并沒有定義虛函數(shù),但是卻從父類中繼承了虛函數(shù),所以在實(shí)例化該類子類對(duì)象的時(shí)候也會(huì)產(chǎn)生一個(gè)虛函數(shù)表,這個(gè)虛函數(shù)表是子類的虛函數(shù)表,但是記錄的子類的虛函數(shù)地址卻是與父類的是一樣的。所以通過子類對(duì)象的虛函數(shù)表指針找到自己的虛函數(shù)表,在自己的虛函數(shù)表找到的要執(zhí)行的函數(shù)指針也是父類的相應(yīng)函數(shù)入口的地址。

(3)如果我們?cè)谧宇愔卸x了從父類繼承來的虛函數(shù),對(duì)于父類來說情況是不變的,對(duì)于子類來說它的虛函數(shù)表與之前的虛函數(shù)表是一樣的,但是此時(shí)子類定義了自己的(從父類那繼承來的)相應(yīng)函數(shù),所以它的虛函數(shù)表當(dāng)中管于這個(gè)函數(shù)的指針就會(huì)覆蓋掉原有的指向父類函數(shù)的指針的值,換句話說就是指向了自己定義的相應(yīng)函數(shù),這樣如果用父類的指針,指向子類的對(duì)象,就會(huì)通過子類對(duì)象當(dāng)中的虛函數(shù)表指針找到子類的虛函數(shù)表,從而通過子類的虛函數(shù)表找到子類的相應(yīng)虛函數(shù)地址,而此時(shí)的地址已經(jīng)是該函數(shù)自己定義的虛函數(shù)入口地址,而不是父類的相應(yīng)虛函數(shù)入口地址,所以執(zhí)行的將會(huì)是子類當(dāng)中的虛函數(shù)。這就是多態(tài)的原理。

(4)純虛函數(shù)

在成員函數(shù)的參數(shù)列表后面寫上“=0”則該成員函數(shù)為純虛函數(shù)。

包含純虛函數(shù)的類叫做抽象類(也叫接口類),抽象類不能實(shí)例化出對(duì)象。

純虛函數(shù)在抽象類中重新定義以后,派生類才能實(shí)現(xiàn)實(shí)例化出對(duì)象。

詳談C++特性:多態(tài)的概念分類和實(shí)現(xiàn)原理

總結(jié):

(1)派生類重寫基類的虛函數(shù)實(shí)現(xiàn)多態(tài),要求函數(shù)名、參數(shù)列表、返回值完全相同(協(xié)變除外)

協(xié)變:基類和派生類中的虛函數(shù)名字和參數(shù)列表相同、返回值類型不同,基類中的虛函數(shù)返回Base*,派生類中的虛函數(shù)返回Derived*

(2)基類中定義了虛函數(shù),在派生類中該函數(shù)始終保持虛函數(shù)的特性。

(3)只有類的非靜態(tài)成員函數(shù)才能定義為虛函數(shù),靜態(tài)成員函數(shù)不能定義為虛函數(shù)。

(4)如果在類外定義虛函數(shù),只能在聲明函數(shù)時(shí)加virtual關(guān)鍵字,定義時(shí)不用加。

(5)構(gòu)造函數(shù)不能定義為虛函數(shù),雖然可以將operator=定義為虛函數(shù),但最好不要這么做,使用時(shí)容易混淆

(6)不要在構(gòu)造函數(shù)和析構(gòu)函數(shù)中調(diào)用虛函數(shù),在構(gòu)造函數(shù)和析構(gòu)函數(shù)中,對(duì)象是不完整的,可能會(huì)出現(xiàn)未定義的行為。

(7)最好將基類的析構(gòu)函數(shù)聲明為虛函數(shù)。(析構(gòu)函數(shù)比較特殊,因?yàn)榕缮惖奈鰳?gòu)函數(shù)跟基類的析構(gòu)函數(shù)名稱不一樣,但是構(gòu)成覆蓋,這里編譯器做了特殊處理)

(8)虛表是對(duì)所有類對(duì)象實(shí)例共用的

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • C++
    C++
    +關(guān)注

    關(guān)注

    21

    文章

    2100

    瀏覽量

    73453
  • 動(dòng)態(tài)多態(tài)

    關(guān)注

    0

    文章

    4

    瀏覽量

    5896
  • 靜態(tài)多態(tài)
    +關(guān)注

    關(guān)注

    0

    文章

    2

    瀏覽量

    5484
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    C++多態(tài)詳解

    在編程語言和類型論中,多態(tài)(英語:polymorphism)指為不同數(shù)據(jù)類型的實(shí)體提供統(tǒng)一的接口。多態(tài)類型(英語:polymorphic type)可以將自身所支持的操作套用到其它類型的值上。
    發(fā)表于 09-20 17:18 ?488次閱讀

    如何完備地實(shí)現(xiàn)C++多態(tài)性?

    如何完備地實(shí)現(xiàn)C++多態(tài)性?虛函數(shù)怎么使用?
    發(fā)表于 04-28 06:44

    STM32 C++代碼封裝初探相關(guān)資料推薦

    一、STM32與面向?qū)ο缶幊躺弦徽轮刑岬搅耍?b class='flag-5'>C++的核心之一就在于面向?qū)ο笏枷搿O啾?b class='flag-5'>C語言常用的面向過程編程,面向?qū)ο缶幊痰膬?yōu)勢(shì)在于繼承、封裝、多態(tài)特性,利用這種思想更有助于我們的程
    發(fā)表于 02-11 06:05

    C++的動(dòng)態(tài)多態(tài)和靜態(tài)多態(tài)

    多態(tài)C++ 中面向?qū)ο蠹夹g(shù)的核心機(jī)制之一包含靜態(tài)多態(tài)和動(dòng)態(tài)多態(tài)它們之間有一定的相似性但是應(yīng)用范圍不同該文論述了這種相似性并重點(diǎn)論述了以模板實(shí)現(xiàn)
    發(fā)表于 06-29 15:41 ?41次下載
    <b class='flag-5'>C++</b>的動(dòng)態(tài)<b class='flag-5'>多態(tài)</b>和靜態(tài)<b class='flag-5'>多態(tài)</b>

    java多態(tài)性的實(shí)現(xiàn)

    Java中多態(tài)性的實(shí)現(xiàn) 什么是多態(tài) 面向?qū)ο蟮娜?b class='flag-5'>特性:封裝、繼承、多態(tài)。從一定角度來看,封裝和繼承幾乎都是為
    發(fā)表于 09-27 10:36 ?9次下載

    C++程序設(shè)計(jì)教程之多態(tài)的詳細(xì)資料說明

    本文檔詳細(xì)介紹的是C++程序設(shè)計(jì)教程之多態(tài)的詳細(xì)資料說明主要內(nèi)容包括了:1.繼承召喚多態(tài) (Inheritance Summon up Polymorphism) ,2.抽象編程的困惑
    發(fā)表于 02-22 10:52 ?9次下載
    <b class='flag-5'>C++</b>程序設(shè)計(jì)教程之<b class='flag-5'>多態(tài)</b>的詳細(xì)資料說明

    C++程序設(shè)計(jì)教程之多態(tài)性與虛函數(shù)的詳細(xì)資料說明

    本文檔詳細(xì)介紹的是C++程序設(shè)計(jì)教程之多態(tài)性與虛函數(shù)的詳細(xì)資料說明主要資料包括了:1 多態(tài)性的概念,2 一個(gè)典型的例子,3 虛函數(shù),4 純虛函數(shù)與抽象類
    發(fā)表于 03-14 16:39 ?5次下載
    <b class='flag-5'>C++</b>程序設(shè)計(jì)教程之<b class='flag-5'>多態(tài)</b>性與虛函數(shù)的詳細(xì)資料說明

    C++三大特性:封裝的概念原理

    我們都知道C++有三大特性:封裝、繼承、多態(tài),之前我總結(jié)過繼承的知識(shí)點(diǎn),現(xiàn)在來總結(jié)一下封裝的相關(guān)知識(shí)!
    的頭像 發(fā)表于 06-29 14:28 ?6419次閱讀
    <b class='flag-5'>C++</b>三大<b class='flag-5'>特性</b>:封裝的<b class='flag-5'>概念</b>原理

    C++基礎(chǔ)語法中的引用、封裝和多態(tài)

    本期是C++基礎(chǔ)語法分享的第六節(jié),今天給大家來分享一下: (1)引用; (2)宏; (3)成員初始化列表; (4)封裝; (5)繼承; (6)多態(tài); 引用 左值引用 常規(guī)引用,一般表示對(duì)象的身份
    的頭像 發(fā)表于 09-12 09:58 ?1280次閱讀

    C++中如何用虛函數(shù)實(shí)現(xiàn)多態(tài)

    01 — C++虛函數(shù)探索 C++是一門面向?qū)ο笳Z言,在C++里運(yùn)行時(shí)多態(tài)是由虛函數(shù)和純虛函數(shù)實(shí)現(xiàn)的,現(xiàn)在我們看下在
    的頭像 發(fā)表于 09-29 14:18 ?1662次閱讀

    STM32 C++編程系列二:STM32 C++代碼封裝初探

    一、STM32與面向?qū)ο缶幊躺弦徽轮刑岬搅耍?b class='flag-5'>C++的核心之一就在于面向?qū)ο笏枷?。相?b class='flag-5'>C語言常用的面向過程編程,面向?qū)ο缶幊痰膬?yōu)勢(shì)在于繼承、封裝、多態(tài)特性,利用這種思想更有助于我們的程
    發(fā)表于 12-08 11:06 ?13次下載
    STM32 <b class='flag-5'>C++</b>編程系列二:STM32 <b class='flag-5'>C++</b>代碼封裝初探

    如何通過poly實(shí)現(xiàn)C++編譯期多態(tài)

      而folly::poly出來的晚一些,主要使用c++的新特性實(shí)現(xiàn)相關(guān)的功能,依賴比較少,所以本文將更多的以poly的實(shí)現(xiàn)來分析編譯期多態(tài)
    的頭像 發(fā)表于 12-05 09:10 ?612次閱讀

    虛函數(shù),C++開發(fā)者如何有效利用

    虛函數(shù)是基類中聲明的成員函數(shù),且使用者期望在派生類中將其重新定義。那么,在 C++ 中,什么是虛函數(shù)呢?在 C++ 中,通常將虛函數(shù)用于實(shí)現(xiàn)運(yùn)行時(shí)多態(tài),該
    的頭像 發(fā)表于 02-11 09:39 ?884次閱讀

    深度解析C++中的虛函數(shù)

    虛函數(shù)作為C++的重要特性,讓人又愛又怕,愛它功能強(qiáng)大,但又怕駕馭不好,讓它反咬一口,今天我們用CPU的角度,撕掉語法的偽裝,重新認(rèn)識(shí)一下虛函數(shù)。 虛函數(shù)是C++實(shí)現(xiàn)面向?qū)ο笤O(shè)計(jì)
    的頭像 發(fā)表于 02-15 11:14 ?794次閱讀
    深度解析<b class='flag-5'>C++</b>中的虛函數(shù)

    C++實(shí)現(xiàn)類似instanceof的方法

    C++多態(tài)與繼承,但是很多人開始學(xué)習(xí)C++,有時(shí)候會(huì)面臨一個(gè)常見問題,就是如何向下轉(zhuǎn)型,特別是不知道具體類型的時(shí)候,這個(gè)時(shí)候就希望C++ 可以向Java或者Python中有insta
    的頭像 發(fā)表于 07-18 10:16 ?499次閱讀
    <b class='flag-5'>C++</b>中<b class='flag-5'>實(shí)現(xiàn)</b>類似instanceof的方法