1. 程式人生 > >C++ 基類的解構函式為什麼需要定義為虛擬函式

C++ 基類的解構函式為什麼需要定義為虛擬函式

主要是因為當通過父類的指標或引用指向子類的物件時,刪除子類時父類的解構函式不能被呼叫造成記憶體洩露

1.當基類的引用指向基類的物件

#include<iostream>
#include<cstring>
#include<cstdlib>
using  namespace std ;

class Base
{
public:
    Base()
    {

        cout << "基類的建構函式被呼叫了" << endl;

    }
     ~Base()
    {

        cout << "基類的解構函式被執行了" <<endl;
    }

};

class Derived :public Base
{
public:
    Derived(char str[] = "")
    {
        if (str == NULL)
        {
            _Dstr = new char[1];
            *_Dstr = '\0';
        }
        else
        {
            _Dstr = new char [strlen(str) + 1];
            strcpy(_Dstr, str);
        }
        cout << "派生類的建構函式被呼叫了" << endl;

    }
    ~Derived()
    {
        if (_Dstr != NULL)
        {
            delete [] _Dstr;
            _Dstr = NULL;
        }
        cout << "派生類的解構函式被執行了" <<endl;
    }
private:
    char *_Dstr;
};


void test()
{
    Base B1;
    Base & b = B1;   //基類的引用或指標指向基類物件。
}

 
 
void test()
{
	Base B1;
	Base & b = B1;   //基類的引用或指標指向基類物件。
}
 
 
int main()
{
	test();
 
	cout << "hello..." <<endl;
	return 0;
}
程式的執行結果:

基類的建構函式被呼叫了
基類的解構函式被執行了
hello...

2.當基類的引用指向派生類的物件(基類是一個抽象類)

#include<iostream>
using  namespace std ;

class Abstract
{
public:
    virtual ~Abstract() = 0;

};

 Abstract:: ~Abstract()
{
    cout << "抽象類的解構函式被執行了" <<endl;
};

class Derived: public Abstract
{
public:
    Derived()
    {
        cout << "派生類的建構函式被執行了" <<endl;
    }
    ~Derived()
    {
        cout << "派生類的解構函式被執行了" << endl;
    }
};

void test()
{
    Derived d;
}

int main()
{
    test();

    cout << "hello..." <<endl;
    return 0;
}

程式的執行結果:

派生類的建構函式被執行了
派生類的解構函式被執行了
抽象類的解構函式被執行了
hello...

總結:

  當基類的物件含有指標成員,需要在刪除物件時清除申請的記憶體單元,如果基類析構物件得不到呼叫將會造成申請的記憶體單元得不到回收,造成記憶體的洩露。