針對虛函式表的結構與布局,寫了乙個程式驗證一下:
首先看單一繼承的情況:
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技術,虛函式技術,...