虛析構函數

類: C++ 權限: 公開 
#include <iostream>
using namespace std;
class Base
{
public: Base()
{
cout<<"constructor in Base"<<endl;
};
virtual void func(void)
{
cout<<"Do in Base!"<<endl;
};
virtual ~Base()
{
cout<<"destructor in Base"<<endl;
};
};
class Derived:public Base
{

public: Derived()
{
cout<<"constructor in Derived"<<endl;
};
void func(void)
{
cout<<"Do in Derived!"<<endl;
};
~Derived()
{
cout<<"destructor in Derived!"<<endl;
}
};
int main(void)
{
Base *p = new Derived;
p->func();
delete 構造函數不能用虛擬,因爲用也沒用,不管是在棧上構造對象,還是在堆上構造對象,也不管你以後是否使用父類的指針或引用來指向或引用這個對象,在構造的那“一瞬間”,總歸要指明要構造對象的具體類型,所以,對象在構造過程中不存在運行時動態綁定的多態行爲。 
你理解這個意思嗎?舉了例子就明白了,通常,假如A是B的父類, 
A* p = new B(); 
則對於虛擬函數f,可以通過A類的指針p直接調用到B類的函數,這就是運行時的多態: 
p->f(); 
但你注意沒有,B類的對象卻必須通過“A* p = new B();”來構造,顯然不能通過“A* p = new A();”來構造一個B類對象——這是荒唐的,這隻能構造一個A類的對象。所以構造函數虛擬無意義。 
但析構函數就不同了,p明明是個A類的指針,如果析構函數不是虛擬的,那麼,你後面就必須這樣才能安全的刪除這個指針: 
delete (B*)p; 
但如果構造函數是虛擬的,就可以在運行時動態綁定到B類的析構函數,直接: 
delete p; 
就可以了。這就是虛析構函數的作用。而事實上,在運行時,你並不是總是能知道p所指對象的實際類型從而進行強制轉換,所以,C++語言既然要支持多態,也就必須支持虛擬析構。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章