1. 程式人生 > >2018/11/7 MFC 學習筆記

2018/11/7 MFC 學習筆記

  • 為什麼解構函式要宣告成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,那就是資源洩露了。