原文連結
Cpp代碼
#include <iostream.h>class Base { public: Base() { mPtr = new int; } ~Base() { delete mPtr; cout<<"Base::Destruction"<<endl;} private: int* mPtr; } ;class Derived : public Base { public: Derived() { mDerived = new long; } ~Derived() { delete mDerived; cout<<"Derived::Destruction"<<endl;} private: long* mDerived; } ;void main() { Base* p = new Derived; delete p; }
輸出結果只有:Base::Destruction以上代碼會產生記憶體泄露,因為new出來的是Derived類資源,採用一個基類的指標來接收,析構的時候,編譯器因為只是知道這個指標是基類的,所以只將基類部分的記憶體析構了,而不會析構子類的,就造成了記憶體泄露,如果將基類的解構函式改成虛函數,就可以避免這種情況,因為虛函數是後綁定,其實就是在虛函數列表中,解構函式將基類的解構函式用實際對象的一組解構函式替換掉了,也就是先執行子類的虛函數再執行父類的虛函數,這樣子類的記憶體析構了,父類的記憶體也釋放了,就不會產生記憶體泄露。 應該為
#include <iostream.h>class Base { public: Base() { mPtr = new int; } virtual ~Base() { delete mPtr; cout<<"Base::Destruction"<<endl;} private: int* mPtr; } ;class Derived : public Base { public: Derived() { mDerived = new long; } ~Derived() { delete mDerived; cout<<"Derived::Destruction"<<endl;} private: long* mDerived; } ;void main() { Base* p = new Derived; delete p; }
註:1.解構函式其實是一個函數,不論子類還是父類,雖然可能看起來名字不一樣。而且解構函式執行過程都是執行子類再到父類。2.多態的時候一定要將解構函式寫成虛函數,防止記憶體泄露,各個子類維護自己內部資料釋放。 virtual 是實現多態的基礎
它使得具體的函數跳轉從編譯時間延遲到運行時然而建構函式的調用是編譯器期間就決定的,因此它不能為虛