C 虛函式表的布局

2021-09-26 14:25:42 字數 1763 閱讀 4827

針對虛函式表的結構與布局,寫了乙個程式驗證一下:

首先看單一繼承的情況:

class base

virtual void y()

virtual void z()

};class derive : public base,public base2

// 重寫

virtual void y1()

virtual void y() // 重寫

virtual void z1()

};

測試程式如下:

base* pppp = new derive();

derive* ppp = dynamic_cast(pppp);

ppp->x(); // 0

ppp->y(); // derive 沒有y函式的情況下是1,derive 有y函式的情況下是1

ppp->z(); // 2

ppp->y1(); // derive 沒有y函式的情況下是3,derive 有y函式的情況下是3

ppp->z1(); // 4

在子類derive覆蓋y()函式和不覆蓋,在虛函式表的位置沒有任何改變。

於是,再加乙個類繼承,**如下:

class base

virtual void y()

virtual void z()

};class base2

virtual void y2()

virtual void z2()

};class derive : public base,public base2

// 重寫

virtual void y1()

virtual void y() // 重寫

virtual void z1()

virtual void z2() // 重寫

};

測試**如下:

base* pppp = new derive();

derive* ppp = dynamic_cast(pppp);

ppp->x(); // 0

ppp->y(); // derive 沒有y函式的情況下是1,derive 有y函式的情況下是1

ppp->z(); // 2

ppp->y1(); // derive 沒有y函式的情況下是3,derive 有y函式的情況下是3

ppp->z1(); // 4

ppp->x2(); // 0

ppp->z2(); // 2 derive 沒有z2函式的情況下是2,derive 有z2函式的情況下是5

對於繼承兩個基類的情況,會有兩個虛函式表,呼叫基類base1和子類自己的函式,函式的索引沒有變化;在子類呼叫基類base2的函式時,會將指標移到第二個虛函式表,然後索引從0開始計算。如果子類重寫了函式,如:z2(),那麼,此函式就會移到第乙個虛函式表的最後。

目前只測試了單一繼承和多個類的繼承,至於菱形繼承沒有進一步測試。

經過測試得出的結論如下:

單一繼承:乙個虛函式表,基類的函式在前面,子類的函式在後面,如果子類過載了基類函式,還是按照基類的順序存放。如果是繼承多個類,會有兩個虛函式表,第乙個基類的依然和之前的一樣,第二個基類中的函式會有乙個單獨的虛函式表,如果子類過載了第二個基類的某個函式,這個函式就會放在第乙個虛函式表的後面。

如有錯誤,歡迎指正。謝謝!

C 虛函式表

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

C 虛函式表

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

C 虛函式表

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