深入解析C 中的虛函式與多型

2022-10-04 04:51:13 字數 1888 閱讀 6653

1.c++中的虛函式

c++中的虛函式的作用主要是實現了多型的機制。關於多型,簡而言之就是用父型別別的指標指向其子類的例項,然後通過父類的指標呼叫實際子類的成員函式。這種技術可以程式設計客棧讓父類的指標有「多種形態」,這是一種泛型技術。所謂泛型技術,說白了就是試圖使用不變的**來實現可變的演算法。比如:模板技術,rtti技術,虛函式技術,要麼是試圖做到在編譯時決議,要麼試圖做到執行時決議。

對c++ 了解的人都應該知道虛函式(virtual function)是通過一張虛函式表(virtual table)和乙個指向虛函式表的指標(vptr)來實現的。虛函式表程式設計客棧,簡稱為vtbl,虛函式表表對實現多型起著至關重要的作用。在這個表中,主要儲存了乙個類中的虛函式的位址,這張表解決了繼承、覆蓋的問題,保證其內容能真實反應實際的函式。每乙個包含虛函式的類的例項都包含乙個cptr指標,指向虛函式表的首位址。我們可以通過這個指標找到要訪問的虛函式的,完成虛函式的呼叫主要包括:找到虛函式表的首位址(vptr),通過cptr找到要使用虛函式位址,呼叫虛函式。那麼使用虛函式大家總要考慮效率的問題,實際上為了提高效率,c++的編譯器是保程式設計客棧證虛函式表的指標存在於物件例項中最前面的位置,這是為了保證取到虛函式表的有最高的效能,這意味著我們通過物件例項的位址得到這張虛函式表,然後通過遍歷表就可以找到其中的虛函式的位址,然後呼叫相應的函式。不妨看看下面的**:

複製** **如下:

#include

using namespace std;

class base

virtual void g()

virtual void h()

};typedef void(*fun)(void);

int main()

通過這個示例,可以看到,通過強行把&b轉成int *,取得虛函式表的位址(vptr),然後,再次取址就可以得到第乙個虛函式的位址了,也就是base::f(),這在上面的程式中得到了驗證(把int* 強制轉成了函式指標)。通過這個示例,我們就可以知道如果要呼叫base::g()和base::h(),其**如下:

複製** **如下:

(fun)*((int*)*(int*)(&b)+0); // base::f()

(fun)*((int*)*(int*)(&b)+1); // base::g()

(fun)*((int*)*(int*)(&b)+2); // base::h()

可以看看虛函式表的圖是怎麼畫的:

大家都知道,多型是通過繼承實現的,那麼我們要說說虛函式繼承的問題。繼承就涉及到了虛函式的覆蓋了,實際上不被覆蓋的虛函式和多型又有什麼聯絡呢?這裡我們討論有覆蓋的虛函式表是什麼樣的,假設存在下面的繼承關係:

看看虛函式表示什麼樣的:

可以發現,base::f()被覆蓋了,這樣若把derive的例項賦值給乙個基類base指標pbase,通過pbase->f();則訪問的是子類中的f()也就是完成了多型。那麼虛函式表中的內容到底是怎麼樣的呢?可以看看下面的四句話就會明白!

1.虛函式按照其宣告順序放於表中。

2.父類的虛函式在子類的虛函式前面。

3.覆蓋的f()函式被放到了虛表中原來父類虛函式的位置。

4.沒有被覆蓋的函式依舊。

2.用虛函式實現多型

看看下面的多型的**:

複製** **如下:

#include

using namespace std;

class base

};class derive : public base

};int main()

//多型**

實現虛函式的**,一定要切記:一定是基類的指標指向子類的物件的位址。首先試著理解一下用虛函式實現多型的原理,如果實在沒理解為什麼虛函式能實現多型,又為什麼這樣實現多型,上網再搜一搜相關的資料!!!

本文標題: 深入解析c++中的虛函式與多型

本文位址:

C 中虛函式與多型

物件導向理論中的3個術語 物件 方法和訊息。物件 object 不言而喻,它是構成系統的基本單位,有屬性和行為兩個要素,在c 中,每個物件都是由資料和函式這兩部分組成的,資料即是物件的屬性,行為稱之為方法 method 方法是對資料的操作,通常由函式實現。呼叫物件中的函式就是向該物件傳送乙個訊息 m...

C 深度解析 34 多型與虛函式

3 小結 前一篇部落格中我們知道,當使用父類的指標 引用 指向子類物件時,子類物件退化為父類物件,只能訪問父類中的成員。也就是說父類的指標不管指向的是父類的物件還是子類的物件,呼叫的都是父類的函式。我們希望根據實際指向的物件型別呼叫重寫函式,指標 引用 指向父類物件時呼叫父類中的成員函式,指向子類物...

C 虛函式與多型

1.1 虛函式概念 1.定義 在乙個類的成員函式前面加上virtual關鍵字,則該函式就稱為虛函式。2.如果乙個函式不是類的成員函式,則該函式不能定義為虛函式。即就是類外面不能使用virtual關鍵字 1.2 純虛函式與抽象類 1.純虛函式 在虛函式的後面加上 0 virtual void disp...