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技...