C 中的虛函式

2021-10-19 14:45:24 字數 2428 閱讀 5782

#includeusing namespace std;

class base

void show()

void show(int)

protected:

int ma;

};class derive :public base

void show()

protected:

int mb;

};int main()

虛函式

如果類裡定義了乙個虛函式,那麼編譯階段,編譯器給這個類型別產生乙個唯一的vftable虛函式表,其中儲存的內容主要是rtti指標和虛函式的位址

base vftable

rtti指標:run-time type information 執行時的型別資訊,指向乙個儲存型別的字串"base"

偏移量:大部分情況下是0

總結:1.當程式執行時,每一張虛函式表都會載入到.rodata(唯讀資料段)區

該類定義的所有物件,它們的vfptr都指向同一張vftable虛函式表中,虛函式位址的起始部分

3.乙個類中只要有乙個虛函式,就會生成vfptr,擁有再多的虛函式不會增加物件記憶體大小,但會增加虛函式表的大小

4.如果派生類中的方法,和基類繼承來的某個方法,返回值、函式名、引數列表都相同,並且基類中該方法是virtual虛函式,那麼派生類中的該方法自動處理成虛函式。這兩個成員方法間的關係是『覆蓋』

所以派生類derive也會生成虛函式表

derive vftable

rtti指標:指向"derive"(實際是乙個rtti型別的物件)

pb->show();//base::show()->derive::show()
如果發現base::show()是普通函式,那麼呼叫的一定是基類的成員,進行靜態繫結call base::show (函式位址)

如果發現base::show()是虛函式,那麼進行動態繫結

mov eax,dword ptr[pb]//取pb記憶體的前四個位元組,即vfptr指向虛函式位址

mov ecx,dword ptr[eax]

call ecx//虛函式的位址

pb->show(int);//虛函式,依然是動態繫結,base::show(int)
cout << sizeof(base) << endl;//4->8

cout << sizeof(derive) << endl;//8->12

cout << typeid(pb).name() << endl;//class base* 不變(靜態型別語言)

cout << typeid(*pb).name() << endl;//class base->class derive

如果base沒有虛函式,*pb識別編譯時期的型別base

如果base有虛函式,*pb識別執行時期的型別。訪問物件中的vfptr,即派生類虛函式表中rtti中儲存的型別

偏移量指vfptr在物件記憶體中的偏移量,在起始部分4個位元組那麼偏移量就是0

實現虛函式的條件?

1.虛函式會產生函式位址儲存在vftable中,因此虛函式依賴物件,物件必須存在(vfptr->vftable->虛函式位址)

2.建構函式不能為虛函式(建構函式完成才有物件)。建構函式中呼叫虛函式也不會發生動態繫結(呼叫任何函式都是靜態繫結),因為乙個派生類構造過程中,先呼叫基類的建構函式,再呼叫派生類建構函式

3.static靜態成員方法不能為虛函式,因為它不需要物件

4.析構函式可以成為虛函式

#includeusing namespace std;

class base

~base()

void show1()

virtual void show2()

protected:

int ma;

};class derive :public base

~derive()

protected:

int mb;

};int main()

所以將基類析構函式寫為虛函式

基類析構函式是虛函式,派生類析構函式自動成為虛函式

virtual ~base() 

/*將基類析構函式寫為虛函式後,派生類析構函式自動成為虛函式

派生類和基類的析構函式視為同名函式,派生類析構函式會覆蓋基類析構函式,但是釋放完派生類記憶體後還是會再去釋放基類記憶體

*/

基類析構函式必須寫為虛函式的情況:

基類的指標/引用指向堆上new出來的派生類物件,delete(基類指標)呼叫析構函式必須發生動態繫結,否則會使派生類析構函式沒有被呼叫到

C 中的虛函式 純虛函式

c 最重要的特性就是多型,而多型,就主要通過虛函式實現的。具體的實現過程是 基類中的函式定義為虛函式,派生類發生覆蓋 即函式名稱 引數列表 返回值型別完全相同 的情況下,派生類中的函式也會自動變成虛函式,不論加不加virtual關鍵字。此時,基類與子類物件中都會存在一張虛函式表 因為含有虛函式 具體...

C 中的虛函式

c 中的虛函式 virtual function 1.簡介 虛函式是c 中用於實現多型 polymorphism 的機制。核心理念就是通過基類訪問派生類定義的函式。假設我們有下面的類層次 class a class b public a 那麼,在使用的時候,我們可以 a a new b a foo ...

C 中的虛函式

c 中的虛函式 一 雖然很難找到一本不討論多型性的c 書籍或雜誌,但是,大多數這類討論使多型性和c 虛函式的使用看起來很難。我打算在這篇文章中通過從幾個方面和結合一些例子使讀者理解在c 中的虛函式實現技術。說明一點,寫這篇文章只是想和大家交流學習經驗因為本人學識淺薄,難免有一些錯誤和不足,希望大家批...