C 虛函式 純虛函式 多型與虛表機制詳解

2021-10-06 08:00:38 字數 1940 閱讀 8709

在類的定義中,前面有virtual關鍵字的成員函式就是虛函式。

注:派生類中的成員函式 與 基類中虛函式同名且同引數的函式,不加virtual也自動成為虛函式。

沒有函式體的虛函式稱作純虛函式,包含純虛函式的類叫抽象類

注:

class a 

};int main()

多型的實現是通過虛函式。

多型的作用是增強程式的可擴充性,即程式需要修改或增加功能的時候,需要改動和增加的**較少。

多型的關鍵在於通過基類指標或引用呼叫乙個虛函式時,編譯階段不能確定到底呼叫的是基類還是派生類的函式,執行時才能夠確定——這叫動態聯編。虛函式因為用了虛函式表機制,呼叫的時候會增加記憶體開銷,具體見下文。

注:在非建構函式,非析構函式的成員函式中呼叫虛函式,是多型;在建構函式和析構函式中呼叫虛函式,不是多型。

補:一般多型指的是上述的動態多型,還有一種靜態多型是通過函式的過載實現的。

非虛函式靜態聯編,效率要比虛函式高,但是不具備動態聯編能力。

每乙個有虛函式的類(或有虛函式的類的派生類)都有乙個虛函式表(陣列),該表列出了各個虛函式位址,該類的任何物件中都放著乙個虛表指標(32位佔4位元組,64位佔8位元組),虛表指標會在執行時動態繫結決定該物件的虛函式位址。

那麼虛函式表是在執行時建立的還是編譯時建立的呢?虛函式表編譯的時候就確定了,而類物件的虛函式指標vptr是在執行階段確定的。(類的函式的呼叫並不是在編譯時就確定的,而是在執行時才確定的,由於編寫**的時候並不能確定被呼叫的是基類的函式還是哪個派生類的函式,所以宣告為虛函式。虛函式和虛函式表是兩個不同的東西,虛函式的呼叫是在執行時才確定的,虛函式表是在編譯時就已經確定的了 。)

/*——參考自c++ primer一書中的案例——*/

1、可觀察到每個類都建立乙個虛函式表,其中:

2、那base類與derived類的位元組大小為什麼是8,12呢?因為虛表指標也會占用乙個儲存位址空間。

與此同時,呼叫虛函式時也要通過虛表指標來定址,因而需要消耗一定量的時間,但這相較於沒有多型人工重寫這些函式的時間量小得多。

3、為什麼呼叫base類的指標下的虛函式,執行的是dervied中的虛函式呢?

若使用指向物件的引用或指標呼叫虛方法,程式將根據物件型別來呼叫方法,而不是指標的型別。

如果派生類沒有重定義虛函式,則會使用基類中的虛函式。

C 多型, 虛函式, 純虛函式

多型 不同物件接收相同的訊息產生不同的動作。多型包括 編譯時多型和 執行時多型 執行時多型是 通過繼承和虛函式來體現的。編譯時多型 運算子過載上。封裝可以隱藏實現細節,使得 模組化 繼承可以擴充套件已存在的 模組 類 它們的目的都是為了 重用。多型也有 重用的功能,還有解決專案中緊耦合的問題,提高程...

多型,虛函式,純虛函式

多型 借助虛函式,基類指標既可以使用基類 父類 的成員函式,也可以使用派生類 子類 的成員函式,它有多種形態,或多種表現方式,這就是多型 簡單說就是同一條語句可以執行不同的操作,看起來有不同表現方式,這就是多型。多型存在的三個條件 注意 派生類 子類 中的虛函式必須覆蓋 不是過載 基類 父類 中的虛...

C 虛函式 虛表和純虛函式

定義 用virtual修飾的成員函式稱為虛函式 重寫 覆蓋 當在子類中定義了乙個與父類完全相同的虛函式時,則稱這個子類的函式重寫 或覆蓋 了父類的函式 例 includeusing namespace std class person virtual void h1 int b class deri...