A* a=new B ,delete a;會不會產生內存泄露了,露了B-A的部分。其中B為A的子類
析構函數在下邊3種情況時被調用:
1.對象生命周期結束,被銷毀時;
2.delete指向對象的指針時,或delete指向對象的基類類型指針,而其基類虛構函數是虛函數時;
3.對象i是對象o的成員,o的析構函數被調用時,對象i的析構函數也被調用。
情況1請看下邊代碼:
#include<iostream.h>
class A
{
?public:
?A()
?{
??cout<<"constructing A"<<endl;
?}?
?~A()
?{
??cout<<"destructing A"<<endl;
?}
?private:
?int a;
};
class B: public A
{
?public:
?B()
?{
??cout<<"constructing B"<<endl;
?}
?~B()
?{
??cout<<"destructing B"<<endl;
?}
?private:
?int b;
};
void main()
{
?B b;
}
運行結果為:
constructing A
constructing B
destructing B
destructing A
上述代碼還說明了一件事:析構函數的調用順序與構造函數的調用順序相反。
情況2則正好說明了為什么基類應該把析構函數聲明為虛函數,請先看下邊的例子:
#include<iostream.h>
class A
{
?public:
?A()
?{
??cout<<"constructing A"<<endl;
?}?
?~A()
?{
??cout<<"destructing A"<<endl;
?}
?private:
?int a;
};
class B: public A
{
?public:
?B()
?{
??cout<<"constructing B"<<endl;
?}
?~B()
?{
??cout<<"destructing B"<<endl;
?}
?private:
?int b;
};
void main()
{
?A* a = new B;
?delete a;
}
運行結果為:
constructing A
constructing B
destructing A
若將class A中的析構函數聲明為虛函數,運行結果將變成:
constructing A
constructing B
destructing B
destructing A
由此還可以看出虛函數還是多態的基礎,才c++中沒有虛函數就無法實現多態。因為不聲明成虛函數就不能“推遲聯編”,所以不能實現多態。這點上和Java不同,java總是“推遲聯編”的,所以也剩了這些麻煩。
扯遠了,再看情況3,通過下邊代碼表示:
#include<iostream.h>
class A
{
?public:
?A()
?{
??cout<<"constructing A"<<endl;
?}
?~A()
?{
??cout<<"destructing A"<<endl;
?}
?private:
?int a;
};
class C
{
?public:
?C()
?{
??cout<<"constructing C"<<endl;
?}
?~C()
?{
??cout<<"destructing C"<<endl;
?}
?private:
??int c;
};
class B: public A
{
?public:
?B()
?{
??cout<<"constructing B"<<endl;
?}
?~B()
?{
??cout<<"destructing B"<<endl;
?}
?private:
?int b;
?C c;
};
void main()
{
?B b;
}
運行結果為:
constructing A
constructing C
constructing B
destructing B
destructing C
destructing A
b的析構函數調用之后,又調用了b的成員c的析構函數,同時再次驗證了析構函數的調用順序與構造函數的調用順序相反。
若將上邊的代碼中的main()函數內容改成
?A* a = new B;
?delete a;
?
由情況2我們知道,這將不會調用class B的析構函數不會被調用,所以class C的析構函數也不會被調用。
正如我們想的,運行結果為:
constructing A
constructing C
constructing B
destructing A
俗話說溫故而知新,我卻不想做什么師,只是希望能夠和大家分享一下對析構函數和虛析構函數的更深的認識。以上代碼在VC++6.0上測試通過,如有疏漏或錯誤的認識請大家指正: