看一些關於虛函數的博客,做了一些總結,列出一些要點備忘。想必,這些也只有我自己了解,畢竟這是我自己想要的。
想要看虛函數的原理可以參考這一篇博客:http://www.BkJia.com/kf/201206/134671.html
1.C++中的虛函數的作用主要是實現了多態的機制。關於多態,簡而言之就是用父類型別的指針指向其子類的實例,然後通過父類的指針調用實際子類的成員函數。
2. 虛函數(Virtual Function)是通過一張虛函數表(Virtual Table)來實現的。簡稱為V-Table。
3. 在這個表中,主是要一個類的虛函數的地址表,這張表解決了繼承、覆蓋的問題,保證其容真實反應實際的函數。
4. 任何妄圖使用父類指針想調用子類中的未覆蓋父類的成員函數的行為都會被編譯器視為非法.
5. 如果父類的虛函數是private或是protected的,但這些非public的虛函數同樣會存在於虛函數表中,所以,我們同樣可以使用訪問虛函數表的方式來訪問這些non-public的虛函數。
6. 如果虛函數在基類與派生類中出現,僅僅是名字相同,而形式參數不同,或者是返回類型不同,那麼即使加上了virtual關鍵字,也是不會進行滯後聯編的。
7. 只有類的成員函數才能說明為虛函數,因為虛函數僅適合用與有繼承關系的類對象,所以普通函數不能說明為虛函數。
8. 靜態成員函數不能是虛函數,因為靜態成員函數的特點是不受限制於某個對象。
9. 內聯(inline)函數不能是虛函數,因為內聯函數不能在運行中動態確定位置。即使虛函數在類的內部定義,但是在編譯的時候系統仍然將它看做是非內聯的。
10.構造函數不能是虛函數,因為構造的時候,對象還是一片未定型的空間,只有構造完成後,對象才是具體類的實例。
11.析構函數可以是虛函數,而且通常聲名為虛函數。
12。如果析構函數不是虛函數,在析構時,刪除的只能是基類的對象,而不能刪除了類的對象。這樣會有一些數據沒清除,造成內存洩漏 。這個舉個例子……
例子如下:
class ClxBase
{
public:
ClxBase() {};
virtual ~ClxBase() {};
virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl;
};
class ClxDerived : public ClxBase
{
public:
ClxDerived() {};
~ClxDerived() {
cout << "Output from the destructor of class ClxDerived!" << endl;
};
void DoSomething() { cout << "Do something in class ClxDerived!" << endl; };
};
ClxBase *pTest = new ClxDerived;
pTest->DoSomething();
delete pTest;
輸出的結果是:
Do something in class ClxDerived!
Output from the destructor of class ClxDerived!
但是,如果把類ClxBase析構函數前的virtual去掉,那輸出結果就是下面的樣子了:
Do something in class ClxDerived!
也就是說,類ClxDerived的析構函數根本沒有被調用!一般情況下類的析構函數裡面都是釋放內存資源,而析構函數不被調用的話就會造成內存洩漏。
摘自 梵聲沐晖