亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

為什么有了虛析構函數,就能先調用子類的析構函數

虛函數表的理論已經大概明白了,但是還是搞不懂,在有虛析構函數的情況下,為什么delete父類的指針,會先找到子類的析構函數。

如果是一般的虛函數,因為父類和子類的函數名字都是一樣的,調用該函數的時候,通過虛函數表,就會找到子類的函數地址,調用相應的函數。

但是虛析構函數,父類和子類的函數名字是不同的,這樣我就想不明白了,delete父類的指針,應該會去找父類的析構函數啊,怎么會先去子類的虛函數表中找到子類的析構函數呢?

正在回答

7 回答

兄弟我在網上看到一種說法,可以解決你的疑惑

總結:虛析構函數的地址存在于虛函數表中,和普通虛函數別無二致,同時也會像普通的虛函數一樣進行覆蓋

雖然父子的析構函數名字不一樣,但是他們占同一個坑(即父子析構函數在虛函數表中的位置是一樣的,否則就不存在多態了)

析構時,到特定的坑中調用該類型的析構函數,其析構函數中又嵌套了很多對父類的析構函數的調用

————————————————

版權聲明:本文為CSDN博主「F_cff」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。

原文鏈接:https://blog.csdn.net/F_cff/article/details/79690470


0 回復 有任何疑惑可以回復我~

兄弟,你的問題我也很疑惑, 子類的虛函數表應該包含父類的虛析構函數和子類的虛擬構函數, 為啥delete的時候調的是子類的虛析構函數呢, 網上的說法都沒說清楚, 你現在懂了嘛

0 回復 有任何疑惑可以回復我~

個人理解:CFather *p = new CSon;? 父類指針p前四個字節里面裝的是虛指針的地址,如果父類有虛析構,那么該指針指向的虛函數列表里第一個元素就是子類的析構函數,當delete p;時,先進入虛函數列表當中執行第一個元素,即子類析構函數,接著再去執行父類本身的析構函數。查看子類虛函數列表當中的元素可以通過如下方式:

pFun pfun =? (pFun)*((int *)*(int *)p + 0);

0 回復 有任何疑惑可以回復我~

問題是兩個指針地址值不一樣,析構的時候,父類怎么回去尋找得到子類去析構呢?有的話,應該父類應該要存有子類析構函數的地址啊

0 回復 有任何疑惑可以回復我~

我的理解:因為父類指針指向的是子類的對象,因為指針指向的都是首地址,而子類對象的首地址也是虛函數表的位置,所以這個父類指針就找到了子類對象的虛函數表,進而找到虛析構函數。

0 回復 有任何疑惑可以回復我~

我覺得是這樣:

虛析構函數,delete父類的指針p,程序會去找父類的指針p指向的地址,該地址就是子類頭部虛函數表指針的地址,由指針p找到子類的虛函數表,從而找到子類的虛析構函數。

3 回復 有任何疑惑可以回復我~
#1

慕瓜2376596

這個回答是正確的。你看聲明指針的語句 Shape* p = new Circle(); 這里 p指針雖然是用Shape父類聲明的,但是他卻指向了子類對象Circle; 即:p指向的地址就是:子類頭部虛函數表指針的地址。由指針p找到子類的虛函數表,從而找到子類的虛析構函數。
2020-05-29 回復 有任何疑惑可以回復我~

虛函數有動態關聯的功能,如果調用基類中的析構函數,而子類中的析構函數卻沒有被調時,如果自類中有自己的在“堆”上開辟的空間的話,而恰好是在子類的析構函數中完成內存回收的話,這樣就會因為沒有執行到子類的析構函數,而導致內存泄漏。所以,析構函數與構造函數相反,系統會首先執行子類的析構函數,再執行父類的析構函數。

0 回復 有任何疑惑可以回復我~
#1

bigfire 提問者

兄弟,你沒明白我的意思。我不理解的是為什么有了虛析構函數,就能調用到子類的析構函數。這個你了解不?
2016-07-18 回復 有任何疑惑可以回復我~

舉報

0/150
提交
取消
C++遠征之多態篇
  • 參與學習       66224    人
  • 解答問題       334    個

本教程將帶領大家體會面向對象三大特性中的多態特性

進入課程

為什么有了虛析構函數,就能先調用子類的析構函數

我要回答 關注問題
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號