為什么有了虛析構函數,就能先調用子類的析構函數
虛函數表的理論已經大概明白了,但是還是搞不懂,在有虛析構函數的情況下,為什么delete父類的指針,會先找到子類的析構函數。
如果是一般的虛函數,因為父類和子類的函數名字都是一樣的,調用該函數的時候,通過虛函數表,就會找到子類的函數地址,調用相應的函數。
但是虛析構函數,父類和子類的函數名字是不同的,這樣我就想不明白了,delete父類的指針,應該會去找父類的析構函數啊,怎么會先去子類的虛函數表中找到子類的析構函數呢?
虛函數表的理論已經大概明白了,但是還是搞不懂,在有虛析構函數的情況下,為什么delete父類的指針,會先找到子類的析構函數。
如果是一般的虛函數,因為父類和子類的函數名字都是一樣的,調用該函數的時候,通過虛函數表,就會找到子類的函數地址,調用相應的函數。
但是虛析構函數,父類和子類的函數名字是不同的,這樣我就想不明白了,delete父類的指針,應該會去找父類的析構函數啊,怎么會先去子類的虛函數表中找到子類的析構函數呢?
2016-07-17
舉報
2020-06-18
兄弟我在網上看到一種說法,可以解決你的疑惑
總結:虛析構函數的地址存在于虛函數表中,和普通虛函數別無二致,同時也會像普通的虛函數一樣進行覆蓋
雖然父子的析構函數名字不一樣,但是他們占同一個坑(即父子析構函數在虛函數表中的位置是一樣的,否則就不存在多態了)
析構時,到特定的坑中調用該類型的析構函數,其析構函數中又嵌套了很多對父類的析構函數的調用
————————————————
版權聲明:本文為CSDN博主「F_cff」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/F_cff/article/details/79690470
2020-06-18
兄弟,你的問題我也很疑惑, 子類的虛函數表應該包含父類的虛析構函數和子類的虛擬構函數, 為啥delete的時候調的是子類的虛析構函數呢, 網上的說法都沒說清楚, 你現在懂了嘛
2020-06-18
個人理解:CFather *p = new CSon;? 父類指針p前四個字節里面裝的是虛指針的地址,如果父類有虛析構,那么該指針指向的虛函數列表里第一個元素就是子類的析構函數,當delete p;時,先進入虛函數列表當中執行第一個元素,即子類析構函數,接著再去執行父類本身的析構函數。查看子類虛函數列表當中的元素可以通過如下方式:
pFun pfun =? (pFun)*((int *)*(int *)p + 0);
2017-05-09
問題是兩個指針地址值不一樣,析構的時候,父類怎么回去尋找得到子類去析構呢?有的話,應該父類應該要存有子類析構函數的地址啊
2016-08-28
我的理解:因為父類指針指向的是子類的對象,因為指針指向的都是首地址,而子類對象的首地址也是虛函數表的位置,所以這個父類指針就找到了子類對象的虛函數表,進而找到虛析構函數。
2016-08-06
我覺得是這樣:
虛析構函數,delete父類的指針p,程序會去找父類的指針p指向的地址,該地址就是子類頭部虛函數表指針的地址,由指針p找到子類的虛函數表,從而找到子類的虛析構函數。
2016-07-18
虛函數有動態關聯的功能,如果調用基類中的析構函數,而子類中的析構函數卻沒有被調時,如果自類中有自己的在“堆”上開辟的空間的話,而恰好是在子類的析構函數中完成內存回收的話,這樣就會因為沒有執行到子類的析構函數,而導致內存泄漏。所以,析構函數與構造函數相反,系統會首先執行子類的析構函數,再執行父類的析構函數。