《effective C++》中的條款14:確定基類有虛析構(gòu)函數(shù)。也就是說,如果某個(gè)類要作為基類來使用,一般使用虛析構(gòu)函數(shù)??聪旅娴睦樱?/p>
class A{
public:
A(){
strA = new char[10];
strcpy(strA, "abc");
}
virtual ~A(){
cout<<"~A() " <<strA<<endl; delete []strA;
}
private:
char* strA;
};
class B: public A
{
public:
B(){
strB = new char[10];
strcpy(strB, "def");
}
~B(){
cout<<"~B() " <<strB<<endl;
delete []strB;
}
private:
char* strB;
};
測(cè)試:
A *p = new B; delete p;
代碼的輸出結(jié)果:
~A()
我們發(fā)現(xiàn)B類的析構(gòu)函數(shù)沒有調(diào)用,導(dǎo)致內(nèi)存泄露。(因?yàn)閯?dòng)態(tài)編譯,在運(yùn)行時(shí)會(huì)檢查有無派生類對(duì)象重載本函數(shù),有則調(diào)用之。)
當(dāng)我們可能通過基類指針刪除派生類對(duì)象時(shí),并且被析構(gòu)的對(duì)象是有重要的析構(gòu)函數(shù)的派生類的對(duì)象,就需要讓基類的析構(gòu)函數(shù)成為虛擬的。
當(dāng)一個(gè)類不準(zhǔn)備作為基類使用時(shí),使析構(gòu)函數(shù)為虛函數(shù)一般是個(gè)壞主意。因?yàn)楫?dāng)類里面有虛函數(shù)的時(shí)候,編譯器會(huì)給類添加一個(gè)虛函數(shù)表,里面來存放虛函數(shù)指針,這樣就會(huì)增加類的存儲(chǔ)空間。所以,只有類要作為基類來使用時(shí),才把析構(gòu)函數(shù)寫成虛函數(shù)。