什麼是虛函式

2021-09-29 19:30:46 字數 1344 閱讀 3130

在某基類中生命為virtual並在乙個或多個派生類中被重新定義的成員函式,用法格式為:

virtual函式返回型別 函式名(引數列表)
實現多型性,通過指向派生類的基類指標或引用,訪問派生類中的同名覆蓋函式。

虛函式繼承是解決多型性的,當用基類指標指向派生類物件的時候,基類指標呼叫虛函式的時候會自動呼叫派生類的虛函式,這就是多型性,也叫動態編聯。

演示,先看下面**:

#include

using

namespace std;

classa}

;classb:

public a};

intmain()

輸出結果是:

this is a

this is b

上面通過呼叫不同類的print實現了不同的策略,不過這不是多型,這是不同型別指標持續的結果而已,我們改一下main函式:

int

main()

輸出結果為:

this is a

this is a

這明顯不是我們需要的結果,而如果我們採用虛函式,將類改動一下,如下:

classa}

;classb:

public a

};

這個時候輸出就是:

this is a

this is b

這就是多型。

上面三種都是對應同名函式的三種關係:

過載:函式名相同,作用域不同,函式引數不同。

覆蓋:基類和派生類中的函式同名,同引數,基類中的函式是虛函式,派生類中的同名函式會覆蓋基類中的同名同參的虛函式。

隱藏:派生類中的函式會隱藏基類的函式。

我們這裡就用上面的類a和b來做解釋,首先上面兩個類裡面都有虛函式,當編譯器發現兩個類中有虛函式存在的時候,就會為他們分別插入一段資料,並且分別為他們見乙個表,那段資料叫做vptr指標,指向的表叫做vtbl,vtbl的作用就是儲存自己類中虛函式的位址,可以看成是乙個陣列,這個資料的每乙個元素存放的就是虛函式的位址。

然後我們建立乙個a類的指標,然後去呼叫print函式,這個時候肯定呼叫的是a::print函式,這操作首先是取出類裡面的vptr的值,這個值就是vtbl的位址,在根據這個值找到vtbl,這個時候vtbl裡面只有a::print的位址,所以直接就是呼叫a::print函式

如果我們指向b型別的指標,這個時候vtbl裡面儲存的就是有a和b的print函式,但是b類裡面的vptr裡面指向的位址是b::print而不是a::print,這是時候就會訪問b::print函式

參考資料:

什麼是虛函式

虛函式聯絡到多型,多型聯絡到繼承。所以本文中都是在繼承層次上做文章。沒了繼承,什麼都沒得談。下面是對c 的虛函式這玩意兒的理解。一,什麼是虛函式 如果不知道虛函式為何物,但有急切的想知道,那你就應該從這裡開始 簡單地說,那些被virtual關鍵字修飾的成員函式,就是虛函式。虛函式的作用,用專業術語來...

建構函式為什麼不能是虛函式

1.從儲存空間角度,虛函式對應乙個指向vtable虛函式表的指標,這大家都知道,可是這個指向vtable的指標其實是儲存在物件的記憶體空間的。問題出來了,如果建構函式是虛的,就需要通過 vtable來呼叫,可是物件還沒有例項化,也就是記憶體空間還沒有,怎麼找vtable呢?所以建構函式不能是虛函式。...

建構函式為什麼不能是虛函式

1.從 儲存空間角度,虛函式對應乙個指向vtable虛函式表的指標,這大家都知道,可是這個指向vtable的指標其實是儲存在物件的記憶體空間的。問題出來了,如果建構函式是虛的,就需要通過 vtable來呼叫,可是物件還沒有例項化,也就是記憶體空間還沒有,怎麼找vtable呢?所以建構函式不能是虛函式...