成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

C++多態(tài)底層刨析(虛函數(shù)指針,虛函數(shù)表)

callmewhy / 3247人閱讀

摘要:當(dāng)子類繼承了父類并且子類重寫了父類的虛函數(shù)之后,我們可以看到此時子類中虛函數(shù)指針對應(yīng)的虛函數(shù)表中存的是子類經(jīng)過重寫的函數(shù)了。

前言:相信小伙伴們在學(xué)習(xí)到C++面向?qū)ο筇匦灾坏亩鄳B(tài)的時候,都或多或少有一些疑惑。搞不清楚多態(tài)在底層是如何實(shí)現(xiàn)的,今天我就帶大家刨析一下多態(tài)的底層實(shí)現(xiàn),了解一下虛函數(shù)指針和虛函數(shù)表到底是什么東西?(注意本文操作環(huán)境是VS2019 x86架構(gòu) 32位機(jī)器)

1 、多態(tài)的定義和分類

1.1 多態(tài)的定義

1.1.1 定義:
多態(tài)按字面的意思就是多種形態(tài)。當(dāng)類之間存在層次結(jié)構(gòu),并且類之間是通過繼承關(guān)聯(lián)時,就會用到多態(tài)。
C++ 多態(tài)意味著調(diào)用成員函數(shù)時,會根據(jù)調(diào)用函數(shù)的對象的類型來執(zhí)行不同的函數(shù)。
----------來自菜鳥教程

1.2 多態(tài)的分類

1.2.1 多態(tài)分為兩類:
·靜態(tài)多態(tài):函數(shù)重載和運(yùn)算符重載屬于靜態(tài)重載,復(fù)用函數(shù)名
·動態(tài)多態(tài):派生類和虛函數(shù)實(shí)現(xiàn)運(yùn)行時多態(tài)
1.2.2 靜態(tài)多態(tài)和動態(tài)多態(tài)的區(qū)別:
·靜態(tài)多態(tài)的函數(shù)地址早綁定–編譯階段確定函數(shù)地址
·動態(tài)多態(tài)的函數(shù)地址晚綁定–運(yùn)行階段確定函數(shù)地址

2、靜態(tài)多態(tài)代碼演示

2.1 靜態(tài)多態(tài)代碼:

#includeusing namespace std;class Father{public:    void speak() {        cout << "爸爸在說話!" << endl;    }};class Son :public Father{public:    void speak() {        cout << "兒子在說話!" << endl;    }};//執(zhí)行說話函數(shù)//地址早被綁定 在編譯階段確定函數(shù)地址void doSpeak(Father &father)//父類引用接收子類對象{    father.speak();}void test01(){    Son son;    doSpeak(son);}int main(){    test01();    return 0;}

2.2 運(yùn)行結(jié)果:

2.3 分析:
在此案例中,派生類和基類中都出現(xiàn)了speak函數(shù),當(dāng)用父類指針或者引用接收子類對象時,程序會執(zhí)行基類中的同名函數(shù),這是為什么呢?因?yàn)楦割愔械膕peak函數(shù)地址在編譯期間就被綁定,所以在執(zhí)行程序時無論傳遞的是哪種對象,執(zhí)行的都是基類中的speak函數(shù)。這就是靜態(tài)動態(tài)的弊端,那么如果想實(shí)現(xiàn)傳入哪種對象就執(zhí)行哪種類的函數(shù),這就需要用到動態(tài)多態(tài)了。

3 、動態(tài)多態(tài)的代碼刨析

動態(tài)多態(tài)滿足條件:
1、有繼承關(guān)系
2、子類重寫父類的虛函數(shù)
動態(tài)多態(tài)的使用:
父類的指針或者引用指向子類對象

3.1 動態(tài)多態(tài)代碼演示

3.1.1動態(tài)多態(tài)代碼

#includeusing namespace std;class Father{public:    virtual void speak() {        cout << "爸爸在說話!" << endl;    }};class Son :public Father{public:    void speak() {        cout << "兒子在說話!" << endl;    }};//執(zhí)行說話函數(shù)//地址早被綁定 在編譯階段確定函數(shù)地址void doSpeak(Father &father)//父類引用接收子類對象{    father.speak();}void test01(){    Son son;    doSpeak(son);}int main(){    test01();    return 0;}

3.1.2 運(yùn)行結(jié)果:

3.1.3 分析:
靜態(tài)多態(tài)變?yōu)閯討B(tài)多態(tài)只需要給父類的函數(shù)加上virtual關(guān)鍵字變?yōu)樘摵瘮?shù)。

3.2 代碼刨析

小知識:在C++中空類也占內(nèi)存,占一個字節(jié)的空間

3.2.1
我們先來看一下父類的函數(shù)前加上virtual關(guān)鍵字,父類的內(nèi)存占用有什么變化?

通過運(yùn)行發(fā)現(xiàn)此時父類所占的空間變成了4個字節(jié),那么這四個字節(jié)到底是存了什么????其實(shí)聰明的小伙伴們可能已經(jīng)猜出來這四個字節(jié)是什么了,沒錯存的就是一個指針。這個指針就叫虛函數(shù)指針,簡寫為vfptr(virtual function pointer). 對于一個類來說,如果類中存在虛函數(shù),那么編譯器就會自動在類中加一條生成虛函數(shù)指針的語句(void * vfptr),并且在類的構(gòu)造函數(shù)中為虛函數(shù)指針進(jìn)行賦值(vfptr=&Father::vtal),此時這個虛函數(shù)指針就會指向虛函數(shù)表。所以,如果對象存在虛函數(shù),那么編譯器就會生成一個指向虛函數(shù)表的指針,所有的虛函數(shù)都存在于這個表中,虛函數(shù)表就可以理解為一個數(shù)組,每個單元用來存放虛函數(shù)的地址。
3.2.2
此時我們在父類中寫兩個虛函數(shù)
然后打開vs2019的調(diào)試功能查看一下對象father可以看到

此時可以發(fā)現(xiàn)父類對象確實(shí)有一個vfptr指針,這個指針對應(yīng)的
表里就是儲存著兩個虛函數(shù)的地址,這兩個函數(shù)都是屬于父類的。
3.2.3
當(dāng)子類繼承了父類并且子類重寫了父類的虛函數(shù)之后,我們可以看到:

此時子類中虛函數(shù)指針對應(yīng)的虛函數(shù)表中存的是子類經(jīng)過重寫的函數(shù)了。所以當(dāng)傳入一個子類對象時通過查詢子類vfptr找到對應(yīng)的虛函數(shù)表,從而找到其中存的函數(shù)地址去執(zhí)行,這也就是為什么動態(tài)多態(tài)可以根據(jù)傳入對象的不同來執(zhí)行不同的語句。

3.2.4 畫圖演示

4、使用VS自帶的開發(fā)人員工具檢驗(yàn)

4.1 找到VS2019開發(fā)人員工具

4.2 查看有虛函數(shù)的父類布局

4.3 查看子類重寫虛函數(shù)之后子類的布局


由此證明,我們的結(jié)論是正確的!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/119812.html

相關(guān)文章

  • 談?wù)凧ava的面向?qū)ο?/b>

    摘要:也就是說,一個實(shí)例變量,在的對象初始化過程中,最多可以被初始化次。當(dāng)所有必要的類都已經(jīng)裝載結(jié)束,開始執(zhí)行方法體,并用創(chuàng)建對象。對子類成員數(shù)據(jù)按照它們聲明的順序初始化,執(zhí)行子類構(gòu)造函數(shù)的其余部分。 類的拷貝和構(gòu)造 C++是默認(rèn)具有拷貝語義的,對于沒有拷貝運(yùn)算符和拷貝構(gòu)造函數(shù)的類,可以直接進(jìn)行二進(jìn)制拷貝,但是Java并不天生支持深拷貝,它的拷貝只是拷貝在堆上的地址,不同的變量引用的是堆上的...

    ormsf 評論0 收藏0
  • C++基礎(chǔ)語法(五)繼承——萬字總結(jié),干貨滿滿

    摘要:繼承方式繼承方式限定了基類成員在派生類中的訪問權(quán)限,包括公有的私有的和受保護(hù)的。所以子類給父類引用賦值也是可以的,相當(dāng)于給子類對象中繼承的父類部分起了別名。如圖成員函數(shù)也是如此,當(dāng)子類與父類具有函數(shù)名相同的函數(shù)時,還是符合就近原則。 ...

    smartlion 評論0 收藏0
  • C++學(xué)習(xí)資料和視頻

    摘要:博主在公眾號后臺設(shè)置了關(guān)鍵字回復(fù),回復(fù)下面的里面的內(nèi)容,可免費(fèi)獲得學(xué)習(xí)視頻和資料。 博主在公眾號后臺設(shè)置了關(guān)鍵字回復(fù), 回復(fù)下面的【】里面的內(nèi)容, 可免費(fèi)獲得C++學(xué)習(xí)視頻和資料。 如回復(fù):C++基礎(chǔ) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? 【C++】 【1】...

    wangshijun 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<