C 探索虛函式表

2021-08-19 16:03:10 字數 2648 閱讀 3452

一.虛函式表

1.虛函式:類的成員函式前面加上virtual關鍵字。

3.虛函式表就像一張地圖,指明了要呼叫的虛函式。

二.虛函式表的小知識

1.乙個類中只要含有虛函式,則一定會生成一張虛表。

(2)乙個類中不含有虛函式,則其物件的監視視窗如下(可以看到a類的物件a就只含有成員變數,沒有虛表指標):

2.物件裡面並不是存放整個虛表的,物件裡面只存放了乙個指向虛表的指標。(由上面圖可以看出,物件裡面只存放乙個虛表指標_vfptr)

如果乙個物件裡面存放整個虛表,不僅會使該物件變得很大,而且會使得與其同類的所有物件裡面都存放乙個虛表,但是每個物件的虛表都是相同的,為了節省空間還有提高效率,應該讓同類的所有物件指向同乙個虛表,這樣只需要每個物件裡面存放乙個指向虛表的指標就可以了。

3.同型別的所有物件共用一塊虛表。

例如:在靜態區定義乙個a的物件a3,在棧上定義兩個a的物件a1和a2,通過監視視窗可以看到a的所有物件a1,a2,a3裡面的虛表指標的內容都相同,都是0x003acc74,表明他們的虛表的位址都相同,所以他們共用同一塊虛表。

三.通過自己編寫的程式列印虛表

1.由上面的圖可以知道,虛表指標放在物件的頭上(在32位的平台上是頭上4個位元組,在64位的平台上是頭上8個位元組)。

2.下面以32位平台為例:

3.若給定乙個物件,我們可以先取物件的前面4個位元組,然後解引用取出頭上4個位元組的內容(即虛表的位址),讓這個虛表以4位元組為單位(因為虛表裡面存放的是虛函式的位址,在32位下是4個位元組),依次往後遍歷,直到遇到0就結束(虛表是以0作為結束標誌)。

4.我們可以將虛表裡面的內容看做int,最後只要以%p的形式列印虛表的內容就可。

5.將虛表的內容看作int,則虛表就相當於乙個存放int的陣列,即int *table.

6.如果給定了虛表int *table,則可以按照下面的方式列印:

void printvftable(int *table)

cout << endl;

}

7.呼叫列印虛表傳的引數如下:

int main()

8.執行結果如下:

(1)定義乙個函式指標,因為a類裡面所有的虛函式返回值都是void,而且無引數,所以函式指標可以定義為:

typedef void(*vfunc)();

(2)列印虛表函式的**進行如下修改:

void printvftable(int *table)

cout << endl;

}

(3)執行結果如下:

四.在64位平台下列印虛表

1.在64位下如果採用上面的方式列印虛表會出現錯誤。因為在64位平台下指標佔8個位元組,而在32位平台下,指標佔四個位元組。

2.所以在64位平台下:應該取物件的頭上8個位元組,解引用取出裡面的內容,然後再按照8位元組為單位遍歷虛表即可。

3.我們直到long long佔8個位元組,因此可以將**進行如下修改:(這個只能在64位的平台執行)

void printvftable(long long *table)

cout << endl;

}int main()

4.執行結果如下:

五.在32位和64位平台都可以執行列印虛表

1.我們知道在32位乙個指標佔4個位元組,在64位平台下,乙個指標佔8個位元組,我們只要解引用出來的是乙個指標型別就可以達到在32位下面每次都按照4位元組遍歷,在64位平台下,每次都按照8位元組遍歷。

2.將**進行如下修改:

void printvftable(int**table)

cout << endl;

}int main()

3.上面的**在64位和32位平台都可以執行。

(1)在64位平台下:

(2)在32位平台下:

C 虛函式表

考慮最簡單的有虛函式的繼承關係 class f class s public f 此時,我們可以定義乙個父類的指標,實際指向乙個子類的物件。呼叫func函式的結果是子類的函式。虛函式在這裡是動態繫結的。f f new s f func 輸出s func 我們知道子類即使不定義虛函式也會繼承該虛函式表...

C 虛函式表

一般來說,對於開發者我們只需要知道虛函式的使用方法,以及虛函式表的存在即可。但面試時往往會遇到更細節的問題,比如讓你實現乙個虛函式機制,雖然不太實用,總歸了解些底層知識也是件好事。但如果有人苦苦相逼一定要拿這個刷人,你就去罵他吧,你才是寫編譯器的,你們全家都是寫編譯器的。唉,我有些失態了.1.虛函式...

C 虛函式表

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