1. 程式人生 > >C++解構函式前加上virtual的原因

C++解構函式前加上virtual的原因

class A

{

public:

virtual void print(){cout<<"This is A"<<endl;}

};

class B : public A

{

public:

void print(){cout<<"This is B"<<endl;}

}

虛擬函式:指向基類指標在操作它的多型類物件時,會根據不同的類物件,呼叫其相應的函式,實現動態繫結

C++解構函式加上virtual是為了防止記憶體洩漏。(假設基類中採用的是非虛解構函式,當刪除基類指標指向的派生類物件時就不會觸發動態繫結,因而只會呼叫基類的解構函式,而不會呼叫派生類的解構函式。那麼在這種情況下,派生類中申請的空間就得不到釋放從而產生記憶體洩漏

。所以,為了防止這種情況的發生,C++中基類的解構函式應採用virtual虛解構函式。)

用在C++實現多型的時候,其基類要加virtual,就可以繫結派生函式的解構函式。


原因跟動態繫結有關,大家都知道,多型是通過虛擬函式實現的,而虛擬函式又是通過動態繫結實現的。

先舉個例子:

class Base
{
    public:
    virtual void function()
    {
        cout<<"this is Base's function"<<endl;
    }        
    
    virtual ~Base()
    {
        cout<<"this is Base's destroy"<<endl;
    }
};

class Derived:public Base
{
    public:
    void function()
    {
        cout<<"this is Derived's function"<<endl;
    }
    
    ~Derived()
    {
        cout<<"this is Derived's destroy"<<endl;
    }
};

int main()
{
    Base *ptr = new Derived();
    ptr->function();
    delete ptr;
    return 0;
}

上面的程式碼,我先寫了虛擬函式function,第31行就是動態繫結,而33行delete刪除的是Base型基類指標,此指標是沒有派生類Derived的解構函式的,所以如果不在基類的解構函式加上virtual的話,就不能動態繫結派生類的解構函式(當然解構函式的動態繫結你可以看出來跟一般函式的動態繫結相比是特殊的,解構函式的虛擬函式不用按照函式名來找對應的的函式)。一句話:基類的解構函式加了virtual就可以動態繫結派生類的解構函式,這樣的話,在執行多型後刪除其物件,就可以在刪除物件的時候執行派生類的析構函數了(當然執行基類的解構函式是一定會的)。否則不會執行派生類的解構函式。


程式碼輸出結果:

this is Derived's function

this is Derived's destroy

this is Base's destroy


你可以嘗試一下把基類的解構函式前的virtual刪掉(第9行),輸出結果將是:

this is Derived's function

this is Base's destroy

 
原文:https://blog.csdn.net/u014453898/article/details/60402586