C 虛函式表解析

2021-07-24 09:41:39 字數 2387 閱讀 7039

c++ 虛函式表解析

陳皓 注意:在上面這個圖中,我在虛函式表的最後多加了乙個結點,這是虛函式表的結束結點,就像字串的結束符「/0」一樣,其標誌了虛函式表的結束。這個結束標誌的值在不同的編譯器下是不同的。在winxp+vs2003下,這個值是null。而在ubuntu 7.10 + linux 2.6.22 + gcc 4.1.3下,這個值是如果1,表示還有下乙個虛函式表,如果值是0,表示是最後乙個虛函式表。

下面,我將分別說明「無覆蓋」和「有覆蓋」時的虛函式表的樣子。沒有覆蓋父類的虛函式是毫無意義的。我之所以要講述沒有覆蓋的情況,主要目的是為了給乙個對比。在比較之下,我們可以更加清楚地知道其內部的具體實現。

一般繼承(無虛函式覆蓋)

下面,再讓我們來看看繼承時的虛函式表是什麼樣的。假設有如下所示的乙個繼承關係:

請注意,在這個繼承關係中,子類沒有過載任何父類的函式。那麼,在派生類的例項中,其虛函式表如下所示:

對於例項:derive d; 的虛函式表如下:

我們可以看到下面幾點:

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

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

我相信聰明的你一定可以參考前面的那個程式,來編寫一段程式來驗證。

一般繼承(有虛函式覆蓋)

覆蓋父類的虛函式是很顯然的事情,不然,虛函式就變得毫無意義。下面,我們來看一下,如果子類中有虛函式過載了父類的虛函式,會是乙個什麼樣子?假設,我們有下面這樣的乙個繼承關係。

我們從表中可以看到下面幾點,

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

2)沒有被覆蓋的函式依舊。

這樣,我們就可以看到對於下面這樣的程式,

base *b = new derive();

b->f();

由b所指的記憶體中的虛函式表的f()的位置已經被derive::f()函式位址所取代,於是在實際呼叫發生時,是derive::f()被呼叫了。這就實現了多型。

多重繼承(無虛函式覆蓋)

下面,再讓我們來看看多重繼承中的情況,假設有下面這樣乙個類的繼承關係。注意:子類並沒有覆蓋父類的函式。

對於子類例項中的虛函式表,是下面這個樣子:

我們可以看到:

1)  每個父類都有自己的虛表。

2)  子類的成員函式被放到了第乙個父類的表中。(所謂的第乙個父類是按照宣告順序來判斷的)

這樣做就是為了解決不同的父類型別的指標指向同乙個子類例項,而能夠呼叫到實際的函式。

多重繼承(有虛函式覆蓋)

下面我們再來看看,如果發生虛函式覆蓋的情況。

下圖中,我們在子類中覆蓋了父類的f()函式。

下面是對於子類例項中的虛函式表的圖:

附錄 二:例程

下面是乙個關於多重繼承的虛函式表訪問的例程:

using namespace std;

class base1

virtual void g()

virtual void h()

}; class base2

virtual void g()

virtual void h()

}; class base3

virtual void g()

virtual void h()

}; class derive : public base1, public base2, public base3

virtual void g1()

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

int main()

{ fun pfun = null;

derive d;

int** pvtab = (int**)&d;

//base1』s vtable

//pfun = (fun)((int)(int)((int*)&d+0)+0);

pfun = (fun)pvtab[0][0];

pfun();

//pfun = (fun)((int)(int)((int*)&d+0)+1);

pfun = (fun)pvtab[0][1];

pfun();

//pfun = (fun)((int)(int)((int*)&d+0)+2);

pfun = (fun)pvtab[0][2];

pfun();

//derive』s vtable

//pfun = (fun)((int)(int)((int*)&d+0)+3);

pfun = (fun)pvtab[0][3];

pfun();

//the tail of the vtable

pfun = (fun)pvtab[0][4];

cout<

C 虛函式表解析

前言 c 中的虛函式的作用主要是實現了多型的機制。關於多型,簡而言之就是用父型別別的指標指向其子類的例項,然後通過父類的指標呼叫實際子類的成員函式。這種技術可以讓父類的指標有 多種形態 這是一種泛型技術。所謂泛型技術,說白了就是試圖使用不變的 來實現可變的演算法。比如 模板技術,rtti技術,虛函式...

C 虛函式表解析

c 中的虛函式的作用主要是實現了多型的機制。關於多型,簡而言之就是用父型別別的指標指向其子類的例項,然後通過父類的指標呼叫實際子類的成員函式。這種技術可以讓父類的指標有 多種形態 這是一種泛型技術。所謂泛型技術,說白了就是試圖使用不變的 來實現可變的演算法。比如 模板技術,rtti技術,虛函式技術,...

C 虛函式表解析

今天我做的筆記 c 中的虛函式的作用主要是實現了多型的機制。關於多型,簡而言之就是用父型別別的指標指向其子類的例項,然後通過父類的指標呼叫實際子類的成員函式。這種技術可以讓父類的指標有 多種形態 這是一種泛型技術。所謂泛型技術,說白了就是試圖使用不變的 來實現可變的演算法。比如 模板技術,rtti技...