C 虛函式原理

2022-04-10 11:57:41 字數 2409 閱讀 7712

類中的成員函式分為靜態成員函式非靜態成員函式,而非靜態成員函式又分為普通函式虛函式

q:為什麼使用虛函式

a: 使用虛函式,我們可以獲得良好的可擴充套件性。在乙個設計比較好的物件導向程式中,大多數函式都是與基類的介面進行通訊。因為使用基類介面時,呼叫基類介面的程式不需要改變就可以適應新類。如果使用者想新增新功能,他就可以從基類繼承並新增相應的新功能。

q:簡述c++虛函式作用及底層實現原理

a: 要點是要答出虛函式表虛函式表指標的作用。

虛函式是用來實現動態繫結的。

c++中虛函式使用虛函式表和虛函式表指標實現,虛函式表是乙個類的虛函式的位址表,用於索引類本身以及父類的虛函式的位址,假如子類重寫了父類的虛函式,則對應在虛函式表中會把對應的虛函式替換為子類的函式的位址(子類中可以不是函式,但是必須同名);虛函式表指標存在於每個物件中(通常出於效率考慮,會放在物件的開始位址處),它指向物件所在類的虛函式表的位址;在多繼承環境下,會存在多個虛函式表指標,分別指向對應不同基類的虛函式表。

虛函式表是每個(有虛函式的)對應乙個。虛函式表指標是每個物件對應乙個。

虛函式表裡只能存放虛函式,不能存放普通函式。

如果乙個函式不是虛函式,那麼對它的呼叫(即該函式的位址)在編譯階段就會確定。呼叫虛函式的話(它的位址)要執行時才能確定。

虛函式的函式入口是動態繫結的。在執行時,程式根據基類指標指向的實際物件,來呼叫該物件對應版本的函式。(用該物件虛函式表指標找到其虛函式表,進而呼叫不同的函式。)(只有是虛函式的情況下才會這麼做(用虛函式表指標去查虛函式表)。非虛函式直接就呼叫自己的。)

follow up:

1. 為什麼需要虛析構函式?(什麼情況下要用虛析構函式?)

在存在類繼承並且析構函式中需要析構某些資源時,析構函式需要是虛函式。否則若使用父類指標指向子類物件,在delete時只會呼叫父類的析構函式,而不能呼叫子類的析構函式,造成記憶體洩露。

2. 乙個物件訪問普通成員函式和虛函式哪個更快?

訪問普通成員函式更快,因為普通成員函式的位址編譯階段就已確定,因此在訪問時直接呼叫對應位址的函式;

而虛函式在呼叫時,需要首先在虛函式表中尋找虛函式所在位址,因此相比普通成員函式速度要慢一些。

3. 析構函式一定是虛函式嗎?

不一定。1. 虛函式效率相對要低一些;2. 有些類並沒有子類,沒必要用虛析構函式。

4. 內聯函式、建構函式、靜態成員函式可以是虛函式嗎?

都不可以。

內聯函式(inline)需要在編譯階段展開(在編譯時就已經確定了),而虛函式是執行時動態繫結的,編譯時無法展開,因此是矛盾的;

建構函式在進行呼叫時還不存在父類和子類的概念,父類只會呼叫父類的建構函式,子類呼叫子類的,因此不存在動態繫結的概念(先有父類才能有子類,構造父類的時候子類還不存在,子類都還沒有怎麼可能在父類裡動態呼叫子類);

靜態成員函式(static)是以為單位的函式,與具體物件無關,虛函式是與物件動態繫結的,因此是兩個矛盾的概念;

5. 建構函式中可以呼叫虛函式嗎?

可以,但是沒有意義,起不到動態繫結的效果。父類建構函式中呼叫的仍然是父類版本的函式,子類中呼叫的仍然是子類版本的函式。

6. 簡述c++中虛繼承的作用及底層實現原理?

虛繼承用於解決多繼承條件下的菱形繼承問題,底層實現原理與編譯器相關,一般通過虛基類指標實現,即各物件中只儲存乙份父類的物件,多繼承時通過虛基類指標引用該公共物件,從而避免菱形繼承中的二義性問題。

ref:

【分析的很有邏輯】

C 虛函式原理

簡單地說,每乙個含有虛函式 無論是其本身的,還是繼承而來的 的類都至少有乙個與之對應的虛函式表,其中存放著該類所有的虛函式對應的函式指標。例 其中 從編譯器的角度來說,b的虛函式表很好構造,d的虛函式表構造過程相對複雜。下面給出了構造d的虛函式表的一種方式 僅供參考 以下面的程式為例 編譯器只知道p...

c 虛函式與虛函式表原理

目錄 用virtual修飾的成員函式叫虛函式 小知識 沒有虛建構函式 不寫虛函式,沒有預設的虛函式 普通函式不影響類的記憶體 class mm protected void testvirtual int main 輸出 1 增加乙個指標的記憶體,32位作業系統多4個位元組 64位作業系統多8個位元...

C 虛函式表原理

一 概述 為了實現c 的多型,c 使用了一種動態繫結的技術。這個技術的核心是虛函式表 下文簡稱虛表 本文介紹虛函式表是如何實現動態繫結的。二 類的虛表 每個包含了虛函式的類都包含乙個虛表。我們知道,當乙個類 a 繼承另乙個類 b 時,類a會繼承類b的函式的呼叫權。所以如果乙個基類包含了虛函式,那麼其...