C 中的虛函式(一)

2021-05-21 20:28:56 字數 2662 閱讀 4950

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

首先,c++通過虛函式實現多型."無論傳送訊息的物件屬於什麼類,它們均傳送具有同一形式的訊息,對訊息的處理方式可能隨接手訊息的物件而變"的處理方式被稱為多型性。"在某個基類上建立起來的類的層次構造中,可以對任何乙個派生類的物件中的同名過程進行呼叫,而被呼叫的過程提供的處理可以隨其所屬的類而變。"虛函式首先是一種成員函式,它可以在該類的派生類中被重新定義並被賦予另外一種處理功能。

class 類名

class 類名:基類名

三、 虛函式在記憶體中的結構

1.我們先看乙個例子:

#include "iostream.h"

#include "string.h"

class a

};int main(int argc, char* argv)

結果如下:size of a = 4

2.如果再新增乙個虛函式:virtual void fun1()

得到相同的結果。如果去掉函式前面的virtual修飾符

class a 

};int main(int argc, char* argv)

結果如下:size of a = 1

3.在看下面的結果:

class a 

int a;

int b;

};int main(int argc, char* argv)

結果如下:size of a = 12

其實虛函式在記憶體中結構是這樣的:

圖一在window2000下指標在記憶體中佔4個位元組,虛函式在乙個虛函式表(vtable)中儲存函式位址。在看下面例子。

class a 

virtual void fun1()

int a;

int b;

};int main(int argc, char* argv)

結果如下:結果如下:

size of a = 4

虛函式的記憶體結構如下,你也可以通過函式指標,先找到虛函式表(vtable),然後訪問每個函式位址來驗證這種結構,在國外**作者是:zeeshan amjad寫的"atl on the hood中有詳細介紹"

圖二4.我們再來看看繼承中虛函式的記憶體結構,先看下面的例子

class a 

};class b

};class c

};class drive : public a, public b, public c ;

int main()

結果如下:size is = 12 ,相信大家一看下面的結構圖就會很清楚,

圖三 5.我們再來看看用虛函式實現多型性,先看個例子:

class a 

};class b :public a

};class c :public a

};class drive : public c

};int main(int argc, char* argv)

結果:a::f

b::f

c::f

d::f

不用解釋,相信大家一看就明白什麼道理!注意:多型不是函式過載

6.用虛函式實現動態連線在編譯期間,c++編譯器根據程式傳遞給函式的引數或者函式返回型別來決定程式使用那個函式,然後編譯器用正確的的函式替換每次啟動。這種基於編譯器的替換被稱為靜態連線,他們在程式執行之前執行。另一方面,當程式執行多型性時,替換是在程式執行期進行的,這種執行期間替換被稱為動態連線。如下例子:

class a;

};class b:public a;

};class c:public a;

};void test(a *a);

int main(int argc, char* argv)

while(1);

cout<

在上面的例子中,如果把類a,b,c中的virtual修飾符去掉,看看列印的結果,然後再看下面乙個例子想想兩者的聯絡。如果把b和c中的virtual修飾符去掉,又會怎樣,結果和沒有去掉一樣。

7.在基類中呼叫繼承類的函式(如果此函式是虛函式才能如此)還是先看例子:

class a 

void show()

};class b : public a

};int main()

列印結果:a::fun

在6中的例子中,test(a *a)其實有乙個繼承類指標向基類指標隱式轉化的過程。可以看出利用虛函式我們可以在基類呼叫繼承類函式。但如果不是虛函式,繼承類指標轉化為基類指標後只可以呼叫基類函式。反之,如果基類指標向繼承類指標轉化的情況怎樣,這只能進行顯示轉化,轉化後的繼承類指標可以呼叫基類和繼承類指標。如下例子:

class a 

};class b : public a

void fun0()

};int main()

C 中的虛函式(一)

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

C 中的虛函式(一)

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

C 中的虛函式 純虛函式

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