淺談多態基類聲明虛析構函數

通過學習我們了解到派生類對象是由積累部分和派生類不恨構成的,那么該派生類對象是如何被析構和夠早的呢?

#include <iostream>

using namespace::std;

class A{

public:

A(){

cout<<“A的構造函數被調用"<<endl;}

~A(){?? cout<<"A的析構函數被調用"<<endl;}? };

class B:public A{

public:

B(){?? cout<<"B的構造函數被調用"<<? endl;}

~B(){? cout<< "B的析構函數被調用" <<endl;}? };

int main(){

B b;

return 0;}

輸出結果

A的構造函數被調用

B的構造函數被調用

B的析構函數被調用

A的析構函數被調用

可以看到:構造一個派生類對象的時候,先調用基類的構造函數,再調用派生類的構造函數,析構一個派生類對象的時候,先調用派生類的析構函數,再調用基類的析構函數。

上述內容講述的是普通派生類的構造和析構過程,對于具有虛函數的派生類的構造和析構過程是怎樣的呢?此時基類的析構函數沒有聲明稱virtual

#include

using namespace::std;

class A{

public:

A(){

cout<<“A的構造函數被調用"<

~A(){?? cout<<"A的析構函數被調用"<<endl;}

virtual do(){ cout<<"a can do sth;"<<endl;}};

class B:public A{

public:

B(){?? cout<<"B的構造函數被調用"<<? endl;}

~B(){? cout<< "B的析構函數被調用" <endl;}

virtual do(){ cout<<"b can do anything ;"<<endl;

int main(){

A *a=new B;

delete a;

return 0;}

運行結果如下

A的構造函數被調用

B的構造函數被調用

A的析構函數被調用

可以看到,當通過A類型的指針來deleteB類型的對象時,只調用了A的析構函數,所以這個對象的派生部分的內存并沒有被釋放,從而造成內存泄露。

所以:當基類中包含有虛函數的時候,析構函數一定要寫成虛析構函數,否則會造成內存泄露。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容