詳解虛函式的實現過程之虛基類(4)

2021-10-12 08:41:32 字數 1196 閱讀 6557

部落格虛函式實現過程3時提到過虛基類,這裡呢,我們來詳細講述一下:

當我們在虛函式的宣告結尾處新增「=0」,這種虛函式就被稱為純虛函式。

它好似乙個沒有實現只有宣告的函式,它的存在就是為了讓類具有抽象類的功能,讓繼承自抽象類的子類都有虛表和虛表指標。

使用過程中,利用抽象類指標可以更好地完成多型工作。

如下分析:

大家想一想,只有宣告卻沒有實現的函式,它的虛表指標指向的函式那是什麼玩意?它還是指向乙個函式指標嗎?這個函式指標指向的地方是**呢?會不會是空?裡面難不成放了乙個null?還是放了乙個報錯?或者直接指向其它函式?等等疑問,如何解決呢?我們直接通過底層彙編**來分析就可以看出來嘍。

它的虛表指標指向了425068(從位址401830所看出來的),接下來我們探索425068位址去看看那裡有個啥呢?

哇哦,原來是乙個 指標,指向的地方是401e90,它是乙個函式_purecall,它用於結束程式,並發出錯誤編碼資訊0x19。

如果當我們定義了多個純虛函式時,那麼虛表裡面存放的是函式指標內容是不是一樣的呢?

兩個純虛函式都是函式_purecall,所以一切都清晰嘍。

總結:由於純虛函式沒有實現**,因此沒有首位址。編譯器為了防止誤呼叫純虛函式,將虛表中儲存的純虛函式的首位址換成函式_purecall,它用於結束程式,並發出錯誤編碼資訊0x19。

根據這一特性,在分析過程中,一旦在虛表中發現函式位址為_purecall函式的位址時,我們就可以高度懷疑此虛表對應的類是乙個虛基類。

虛函式系列:

詳解虛函式的實現過程之初探虛表(1)

詳解虛函式的實現過程之單繼承(2)

詳解虛函式的實現過程之多重繼承(3)

詳解虛函式的實現過程之虛基類(4)

詳解虛函式的實現過程之菱形繼承(5)

虛基類 虛函式和純虛基類

首先看乙個例子 class base class child1 public base class child2 public base void main else p print 函式呼叫的時候,檢視虛表,根據p的位址首先從虛表裡面查詢要呼叫的函式 這裡呼叫child2的print 函式 ret...

虛基類 虛函式 純虛函式講解

虛基類 在說明其作用前先看一段 從 中可以看出類b c都繼承了類a的ivalue成員,因此類b c都有乙個成員變數ivalue 而類d又繼承了b c,這樣類d就有乙個重名的成員 ivalue 乙個是從類b中繼承過來的,乙個是從類c中繼承過來的 在主函式中呼叫d.ivalue 因為類d有乙個重名的成員...

虛函式 虛基類 抽象類

一 虛基類 解決二義性,防止雙份拷貝間接基類。否則得用作用域分辨符來區分進行的多個拷貝 將共同基類設定為虛函式,這是從不同的路徑繼承過來的同名資料成員在記憶體中就只有乙個拷貝,同乙個函式名也只有乙個對映。虛基類的宣告是在派生類的定義過程中進行的,語法形式為 class 派生類名 virtual繼承方...