通過學習我們了解到派生類對象是由積累部分和派生類不恨構成的,那么該派生類對象是如何被析構和夠早的呢?
#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的析構函數,所以這個對象的派生部分的內存并沒有被釋放,從而造成內存泄露。
所以:當基類中包含有虛函數的時候,析構函數一定要寫成虛析構函數,否則會造成內存泄露。