C/C++—— C++中定義虛解構函式的原因

readyao發表於2016-04-04

C++中定義虛解構函式的原因

如果類中有虛擬函式,一般將該類的解構函式定義為虛擬函式。

在下面的例子中,沒有將解構函式定義為虛擬函式:

#include "iostream"
using namespace std;

class Parent
{
public:
    Parent(int a = 0)
    {
        cout << "Parent()" << endl;
        this->a = a;
    }
    //virtual ~Parent()
    ~Parent()
    {
        cout<<"~Parent()"<<endl;
    }

private:
    int a;
};

class Child : public Parent
{
public:
    Child(int b = 0)
    {
        cout<<"Child()"<<endl;
        this->b = b;
    }
    ~Child()
    {
        cout<<"~Child()"<<endl;
    }
private:
    int b ;
};

//在父類中宣告虛解構函式的原因
//通過父類指標,把所有的子類解構函式都執行一遍。。。
void howtoDel(Parent *pbase)
{
    delete pbase;
}

int main()
{
    Child *pc1 = new Child();
    howtoDel(pc1);

    cout << "***********************" << endl;

    Parent *pp1 = new Parent;
    howtoDel(pp1);

    return 0;
}

輸出:
Parent()
Child()
~Parent()


Parent()
~Parent()

可以看到執行howtoDel(pc1);析構子類物件的時候,僅僅呼叫了父類的解構函式,而沒有根據傳入的子類物件就呼叫子類的解構函式。

將解構函式定義為虛擬函式:

#include "iostream"
using namespace std;

class Parent
{
public:
    Parent(int a = 0)
    {
        cout << "Parent()" << endl;
        this->a = a;
    }

    virtual ~Parent()
    {
        cout<<"~Parent()"<<endl;
    }

private:
    int a;
};

class Child : public Parent
{
public:
    Child(int b = 0)
    {
        cout<<"Child()"<<endl;
        this->b = b;
    }
    ~Child()
    {
        cout<<"~Child()"<<endl;
    }
private:
    int b ;
};

//在父類中宣告虛解構函式的原因
//通過父類指標,把所有的子類解構函式都執行一遍。。。
void howtoDel(Parent *pbase)
{
    delete pbase;
}

int main()
{
    Child *pc1 = new Child();
    howtoDel(pc1);

    cout << "***********************" << endl;

    Parent *pp1 = new Parent;
    howtoDel(pp1);

    return 0;
}

輸出:
Parent()
Child()
~Child()
~Parent()


Parent()
~Parent()

可以看到執行howtoDel(pc1);析構子類物件的時候,呼叫了父類的解構函式,也根據傳入的子類物件呼叫子類的解構函式。(還可以看到在子類物件中建構函式和解構函式執行的順序是相反的)

在父類中宣告虛解構函式的原因:通過父類指標,把所有的子類解構函式都執行一遍。這也是多型現象。

相關文章