C++繼承中的虛解構函式

來源:互聯網
上載者:User

看看下面程式有什麼錯誤:

#include <iostream>
using namespace std;

class Father
{
public:
Father(){};
~Father(){};
};

class Son:public Father
{
public:
Son(){};
~Son(){};
};

int main()
{
Father *pfather=new Son;
delete pfather;
pfather=NULL;

return 0;
}

該程式在VC++6.0運行後並未發生錯誤,何解?

修改上面程式如下:

#include <iostream>
using namespace std;

class Father
{
public:
Father(){cout<<"contructor Father!"<<endl;};
~Father(){cout<<"destructor Father!"<<endl;};
};

class Son:public Father
{
public:
Son(){cout<<"contructor Son!"<<endl;};
~Son(){cout<<"destructor Son!"<<endl;};
};

int main()
{
Father *pfather=new Son;
delete pfather;
pfather=NULL;

return 0;
}

運行結果:

contructor Father!
contructor Son!
destructor Father!

       顯然衍生類別Son並沒有析構,馬上引出了C++繼承中的虛解構函式問題。

(1)基類的的解構函式不是虛函數的話,刪除指標時,只有其類的記憶體被釋放,衍生類別的沒有。這樣就記憶體流失了。

(2)解構函式不是虛函數的話,直接按指標類型調用該類型的解構函式代碼,因為指標類型是基類,所以直接調用基類解構函式代碼。

(3)問:啥已經delete p了還能給p賦值啊。。。不解,求高人指點??

       答:delete是刪除指標p指向的執行個體,p指標本身依然存在,delete後將p置為空白值是常用做法,空值一般寫成NULL宏,其實就是0。因為記憶體0位置是不允許訪問的,delete 0操作編譯器可以判斷是錯誤操作不會執行,因此將p置為空白值0是很安全的做法。

(4)養成習慣:基類的析構一定virtual。

(5)當基類指標指向衍生類別的時候,如果解構函式不聲明為虛函數,在析構的時候,不會調用衍生類別的解構函式,從而導致記憶體泄露。

(6)子類對象建立時先調用父類建構函式然後在調用子類建構函式,在清除對象時順序相反,所以delete p只清除了父類,而子類沒有清除。。。

(7)當基類對象的指標或引用調用衍生類別對象時,如果基類的解構函式不是虛解構函式,則通過基類指標或引用對衍生類別的析構是不徹底的。

 

後語:

(1) 對於這個程式,實際上是沒有關係的,delete pfather雖然只調用了Father類的解構函式,但是程式運行完成,退出main函數後,Son類的部分資料也會被自動清除。
(2)那麼什麼時候才要用虛解構函式呢?通常情況下,程式員的經驗是,當類中存在虛函數時要把解構函式寫成virtual,因為類中存在虛函數,就說明它有想要讓基類指標或引用指向衍生類別對象的情況,此時如果衍生類別的建構函式中有用new動態產生的記憶體,那麼在其解構函式中務必要delete這個資料,但是一般的像以上這種程式,這種操作只調用了基類的解構函式,而標記成虛解構函式的話,系統會先調用衍生類別的解構函式,再調用基類本身的解構函式。 (3)一般情況下,在類中有指標成員的時候要寫copy建構函式,賦值操作符重載和解構函式。 

修改後程式:

#include <iostream>
using namespace std;

class Father
{
public:
Father(){cout<<"contructor Father!"<<endl;};
virtual ~Father(){cout<<"destructor Father!"<<endl;};
};

class Son:public Father
{
public:
Son(){cout<<"contructor Son!"<<endl;};
~Son(){cout<<"destructor Son!"<<endl;};
};

int main()
{
Father *pfather=new Son;
delete pfather;
pfather=NULL;

return 0;
}

運行結果:

contructor Father!
contructor Son!
destructor Son!
destructor Father!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.