繼承 建構函式 析構函式
類繼承中建構函式和析構函式的呼叫
現在,有三個類,類的定義如下
class ca
這個程式執行結果是
ca constructor
cb constructor
cc constructor
cc desstructor
cb desstructor
ca desstructor
靠,太簡單了,乙個雞蛋飛過來了,:(
繼續……………………
(2) 再做第二個試驗之前,先做一點小小修改
~ca()
yeah
結果一模一樣哦
ca constructor
cb constructor
cc constructor
cc desstructor
cb desstructor
ca desstructor
但是如果把virtual ~ca()
執行結果
ca constructor
cb constructor
cc constructor
cc desstructor
cb desstructor
ca desstructor
取消ca中的虛析構函式,那麼,ca,cb,cc中沒有虛析構函式
那麼3中**執行結果如下
ca constructor
cb constructor
cc constructor
cb desstructor
ca desstructor
只調到cb的析構哦,
繼續試驗,ca,cb,cc中,只有cb是虛析構函式
3中**執行如下
ca constructor
cb constructor
cc constructor
cc desstructor
cb desstructor
ca desstructor
所以,如果是cb指向派生類,只要cb或者其基類中存在虛析構函式,那麼也是所有的析構函式都呼叫的了
繼續………………
(4)修改main **如下
int main()
如果a的析構函式是虛的,那麼情況如2,不多說了
如果是ca的析構函式不是虛的,而cb或者cc的析構函式是虛擬的,那麼在呼叫delete p;會出現記憶體錯誤
expression:_block_type_is_valid(phead->nblockuse)
是在釋放記憶體的時候出現這樣的錯誤
上網查了一下,_block_type_is_valid是用來檢測記憶體有效性巨集中的乙個,這個錯誤說明指標使用出現了問題
後來想了一想,應該是因為繼承類中出現了虛函式,所以多了乙個指向虛函式表的指標,而基類中乙個虛函式都沒有,所以也沒有這個指標啦
所以在delete的時候就出現了記憶體錯,事實證明,這個猜想應該是站得住腳的,在ca中新增乙個虛函式,即使的空的虛函式,也不會出現記憶體錯,
關於這個問題,我想在下次繼續討論吧,這裡不深入進去了,
回到正題,在ca中新增乙個空的,任意的虛函式以後,執行正確了,
執行結果是
ca constructor
cb constructor
cc constructor
ca desstructor
這與(2)中的情況是一樣的,只要ca的析構函式不是虛擬的,就只能呼叫ca的析構了
最後來看一種非常bt的做法
(5)ca cb cc中的析構函式,誰是虛擬的,無所謂,隨便
修改main **如下
int main()
執行結果
ca constructor
cb constructor
cc constructor
下面呢???下面沒有了,暈……………………
這種情況,構造了乙個cc的物件,然後呢,沒有調析構函式,直接把申請的
記憶體釋放了,最好不要這樣用咯。
好了,最後,上面,基本上把所有的,我能想到的情況都整理了一下,
總結一下:
如c1 * p = new c2();
delete p;
這樣的**
這裡,c1是c2的基類,c1可能是c2的爸爸,可能是爺爺,可能是爸爸的爺爺,可能是爺爺的爺爺…………………………
那麼首先,呼叫的建構函式是
從c2的第乙個祖先一直到c2………………。和c1是什麼沒關係
在delete p的時候,那麼有以下幾種情況:
1) c1或者c1的祖先(基類)中,含有虛析構函式,那麼呼叫的析構函式的順序是從c2一直到c2的第乙個祖先(#add最開始的祖先)
2)如果c1或者c1的祖先中,沒有乙個是類是含有虛析構函式的,那麼呼叫的是從c1一直到c1的(也是c2的)第乙個祖先的(#add表述有待細思)
3)如果c1是void,那就什麼析構都不呼叫了。
如果乙個類,作為多型的基類,那麼盡量把析構函式宣告成虛擬的,不然………………,
好了,就此打住吧,關於4中的記憶體錯誤,下次再談論吧,專案要開始了,又要忙了,哭去了……………………
參考書籍
《effective c++》
類繼承中建構函式和析構函式的呼叫
類繼承中建構函式和析構函式的呼叫 現在,有三個類,類的定義如下 class ca class cb public ca 這個程式執行結果是 ca constructor cb constructor cc constructor cc desstructor cb desstructor ca de...
類 建構函式和析構函式
一.類 類定義的變數就是物件 1.建構函式 只有 建立物件的時候系統自動呼叫的函式 初始化物件 1 建構函式名與類名相同 2 建構函式沒有返回值 3 建構函式可以過載 注意 關於建構函式 1 如果建構函式被呼叫了,則一定有乙個新物件被建立了 2 如果有乙個新物件被建立,則一定有乙個建構函式被呼叫了 ...
繼承中的構造和析構函式
子類物件在建立時首先會呼叫父類的建構函式,在父類的建構函式執行結束後,再執行子類的建構函式。當父類的建構函式有引數時,需要在子類的初始化列表中顯示呼叫。析構函式的呼叫的先後順序與建構函式相反 結論 建構函式 先呼叫父類 再呼叫子類 析構函式 先呼叫子類 再呼叫父類 如下所示 include usin...