類繼承中建構函式和析構函式的呼叫

2021-07-14 07:48:25 字數 2465 閱讀 6329

類繼承中建構函式和析構函式的呼叫

現在,有三個類,類的定義如下

class ca

;class cb:public 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;會出現記憶體錯誤

:_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的第乙個祖先

2)如果c1或者c1的祖先中,沒有乙個是類是含有虛析構函式的,那麼呼叫的是從c1一直到c1(也是c2的)的第乙個祖先的

3)如果c1是void,那就什麼析構都不呼叫了。

如果乙個類,作為多型的基類,那麼盡量把析構函式宣告成虛擬的,不然………………,

繼承中的構造和析構函式

子類物件在建立時首先會呼叫父類的建構函式,在父類的建構函式執行結束後,再執行子類的建構函式。當父類的建構函式有引數時,需要在子類的初始化列表中顯示呼叫。析構函式的呼叫的先後順序與建構函式相反 結論 建構函式 先呼叫父類 再呼叫子類 析構函式 先呼叫子類 再呼叫父類 如下所示 include usin...

類繼承中建構函式和析構函式地呼叫

繼承 建構函式 析構函式 類繼承中建構函式和析構函式的呼叫 現在,有三個類,類的定義如下 class ca 這個程式執行結果是 ca constructor cb constructor cc constructor cc desstructor cb desstructor ca desstruc...

C 繼承中的建構函式和析構函式

1 繼承中建構函式和析構函式呼叫順序 a 呼叫父類建構函式 b 呼叫其他成員的建構函式 c 呼叫子類建構函式 d 析構呼叫順序相反。include using namespace std class base public base cout base中的預設構造函式呼叫 2 子類預設呼叫父類的預設...