2018/11/7 MFC 學習筆記
阿新 • • 發佈:2018-11-22
- 為什麼解構函式要宣告成virtual呢?
因為,如果delete一個基類的指標時, 如果它指向的是一個子類的物件,那麼解構函式不為虛就會導致無法呼叫子類解構函式,從而導致資源洩露。
當然,另一種做法是將基類解構函式設為protected.
舉例:
#include <iostream> using namespace std; class Father { public: int m_fMember; Father(){m_fMember=1;} ~Father(){cout<<m_fMember<<endl;} }; class Child : public Father{ public: int m_cMember; Child(){m_cMember=2;} ~Child(){cout<<m_cMember<<endl;} }; int main(int argc, char** argv) { Father* pObj1 = new Child(); delete pObj1; cout<<"--"<<endl; Child* pObj2 = new Child(); delete pObj2; return 0; }
執行結果:
1
2
1
如果不用virtual函式,是沒有執行期繫結一說的,比如pObj1這個指標,其實它是Child物件,但是在釋放時,~Child()方法並沒有被呼叫。
僅呼叫了~Father方法。為什麼呢?
因為沒有用virtual,就是編譯期繫結,當你在編譯時gcc/g++只知道pObj1是個Father物件,所以在delete時就去呼叫Father的析構了。
而如果定義成virtual
~Father時,結果就是一定會析構Child,這就是為什麼解構函式都要用virtual,因為沒人知道會不會有子類繼承,否則一旦繼承,發生這樣的事,解構函式裡萬一釋放了些資源,比如SOCKET,比如memory,那就是資源洩露了。