問:虛析構函數的作用是什麼?
答:用基類指針刪除派生類的對象時,讓派生類的析構函數可以被調用;
答案涉及到幾個重要信息:
第一:基類指針,也就是說聲明的指針必須是基類或者是還有派生類的派生類,或者說一定不是最底層派生類;
第二:派生類的對象,生成的對象一定要是派生類的對象,如果new的對象本身就是聲明的類,那也沒必要用虛析構,浪費空間;
第三:派生類析構函數,只要滿足前面兩個條件信息,基類的析構函數(確切來說是派生類對象的聲明類)一定要用虛析構函數;
虛析構函數,在基類和派生類之間,通過基類new一個派生類對象,在後面析構的時候,如果基類的析構函數不爲虛析構,將不會執行派生類的析構函數,如下:
#define CLASS(ID) class ID \
{ \
public: \
ID(){ cout << #ID " constructor \n"; } \
~ID(){ cout << #ID " deconsturctor \n"; } \
}
CLASS(Base1);
CLASS(Memb1);
CLASS(Memb2);
CLASS(Memb3);
CLASS(Memb4);
class Derived1 :public Base1
{
public:
Derived1(){ cout << "Derived1 constructor \n"; }
~Derived1(){ cout << "Derived1 deconstructor \n"; }
static const int s;
protected:
private:
Memb1 m1;
Memb2 m2;
};
class Derived2 :public Derived1
{
public:
Derived2(){ cout << "Derived2 constructor \n"; }
~Derived2(){ cout << "Derived2 deconstructor \n"; }
Memb3 m3;
Memb4 m4;
};
int _tmain(int argc, _TCHAR* argv[])
{
Base1 *pd2 = new Derived2;
cout << sizeof(Derived1) << endl;
cout << sizeof(Derived2) << endl;
delete pd2;
getchar();
return 0;
}
1.如果Base1析構前面不加關鍵詞virtual,執行結果如下:
結論:並不是每一個類的析構函數都要寫成虛析構函數,因爲這會給類增加儲存空間,只有當一個類被用來做爲基類,且實例化爲派生類的時候才需要寫成虛函數;
也就是說如果用derived1 *pd = new derived1 ,這個時候就不需要寫虛構函數,但如果new derived2的話就必須將derived1的析構函數寫成虛析構,不然derived2的析構函數將不會運行,但不管是第一種情況還是第二種情況,base1的析構函數都會運行;