派生類的析構函式不負責撤銷基類物件的成員,編譯器總是顯式呼叫派生類物件基類部分的析構函式。
這句話的含義是:我們定義派生類的析構函式時,不用管基類部分的成員,只撤銷派生類自己的成員即可(如果需要的話)。編譯器會自己呼叫基類的析構函式。我們不用在派生類的析構函式中顯示呼叫它。
另:不管我們定不定義自己的析構函式,編譯器都會合成預設的版本;這一點與建構函式不同。
例子:
class base4
//基類的一般建構函式
base4() :i(0), j(5203132) //基類的預設建構函式
~base4()
void show_base()
public:
int i;
private:
int j;
};class d4 :public base4
//派生類的預設建構函式
d4(int ii, int jj, int kk) :base4(ii, jj), k(kk) //派生類的一般建構函式
d4(int kk) : k(kk) {}//派生類的一般建構函式,隱式呼叫基類的預設建構函式
~d4()
int k;
void show_d()
};//主函式
int main()
執行結果:
從上面我們看到,當我們delete pd4的時候,先呼叫了派生類的析構函式,然後又自動呼叫了基類的析構函式。
處理繼承層次中的物件時,指標的靜態型別可能與被刪除物件的動態型別不同,可能會刪除實際指向派生類物件的基類型別指標,此種行為是未定義的。
型別定義不變,修改主函式為如下所示:
//主函式
int main()
乙個指向基類的指標,實際指向了乙個派生類,如此呼叫delete結果會如何呢?
很明顯,只有基類的析構函式被呼叫,派生類的析構函式喂被呼叫。如果派生類中新增了動態分配的成員,則這部分成員的記憶體未被釋放,發生記憶體洩露。
但是,基類指標指向派生類物件的情況又是經常遇到,不可避免的。所以應該怎樣處理這種情況?
答案就是在基類中定義virtual 析構函式。
我們將基類定義中的析構函式改為virtual析構函式,其他不變:
class base4
//基類的一般建構函式
base4() :i(0), j(5203132) //基類的預設建構函式
virtual ~base4() //虛析構函式
顯然,派生類和基類的析構函式都被呼叫了,不會有記憶體洩漏發生。
如果繼承層次中根類的析構函式為虛函式,則派生類析構函式也是虛函式,不論是自己定義的還是合成的;
複製控制成員3法則:如果類需要析構函式,則它也需要賦值操作符和複製建構函式。
但是,基類的虛析構函式是三法則的乙個重要例外:基類幾乎總是需要虛析構函式,但並不一定需要賦值操作符和複製建構函式。
建構函式和賦值操作符不是虛函式。
c 學習筆記 析構函式
宣告 註明 出處 析構函式 在建立物件的時候系統會自動呼叫建構函式,在物件需要被銷毀的時候同樣系統會自動呼叫乙個函式 析構函式與構造函式呼叫順序是反轉過來的,先呼叫建構函式的後呼叫析構函式。include using namespace std class test test private int...
關於繼承中的析構函式
class clxbase clxbase virtual void dosomething class clxderived public clxbase clxderived void dosomething int main clxderived p new clxderived 情況 clx...
關於繼承中的析構函式
include using namespace std class base 輸出 derived f base f 為什麼呼叫了基類的析構函式,虛函式表就改變了?這樣的問題,有乙個最實用的方法,就是去跟一下彙編的 當然了這需要你懂一點點的組合語言.問題的原因就是 當你呼叫基類的析構函式d.base...