課程
/后端開發
/C++
/C++遠征之多態篇
如果在父類中定義了虛函數 子類中沒有同名的虛函數,那么子類公有繼承父類時會把虛函數繼承過去嗎
2015-12-28
源自:C++遠征之多態篇 2-2
正在回答
不一定,如果是private權限的,就不會,其它情況會,這樣就算不是虛函數也是一樣的。
子類繼承父類,在創建類的時候就會有一個虛函數表的概念,如果子類沒重寫同名函數,子類的虛函數表關于該函數的入口地址就會指向父類的該函數的代碼入口地址
qq_圓圓_0 提問者
父類函數如果是虛函數,子類的同名函數(參數也要相同哦)就一定是虛函數,子類的子類也一樣
父類函數不是虛函數,子類同名函數是虛函數,編譯是沒有問題的,如果沒有父類指針指向子類對象的操作也是沒有問題的,但是有父類指針指向子類對象的操作時,操作的函數會是父類的函數,至此都沒有什么問題,但是在父類的指針釋放內存時,系統就會出問題。這時候如果子類還有孫子類,那么子類指針指向孫子類以及重孫子類,都會是覆蓋,也就是調用同名函數的時候,執行的都是實際對象的函數實現。但是父類指針指向孫子類以及重孫子類與指向子類的效果是一樣的。這是我 實測的結果,在delete父類指針時,內存無法釋放,系統就出問題了。
我分析了一下,父類函數不是虛函數,在子類修飾為虛函數,這時候,父類的虛函數表中指向假設0x12345內存地址,子類的虛函數表也應該是指向0x12345,這樣在實例化類的時候,由于父類中該函數是非virtual的,子類的指向也不會變,所以執行結果就是父類與子類的該函數執行父類的函數實現。父類指針指向孫子類的時候,孫子類的虛函數表由于子類聲明為虛函數,就指向假設0x67890內存地址,由于父類的該函數是非virtual的,所以孫子類對象的該函數在虛函數表中要以父類的地址為準,而不會用0x67890覆蓋掉父類的0x12345,所以執行結果仍是父類的實現。這時候子類指針指向孫子類的時候,就與咱學的一樣嘍,執行結果是孫子類的實現。
再來說一下釋放內存出的問題,具體我還真分析不出來,不過如果父類的析構函數是虛析構函數的話,內存的釋放也是沒有問題的,所以我們其它的不管(不管業務是否有業務需要),析構函數最好都加上virtual關鍵字。對于如果有可能被繼承的類,其函數最好都聲明稱虛函數,這樣繼承才有意義,才可以讓你的邏輯在運行時決定使用哪個具體實現(多態)。virtual應該就是為了實現面向對象中的多態才誕生的吧
不用不好意思,學習哪不會說出來咱們一起討論,吃透了,學會了才是我們的目的。
太陽雨下 回復 qq_圓圓_0 提問者
舉報
本教程將帶領大家體會面向對象三大特性中的多態特性
Copyright ? 2025 imooc.com All Rights Reserved | 京ICP備12003892號-11 京公網安備11010802030151號
購課補貼聯系客服咨詢優惠詳情
慕課網APP您的移動學習伙伴
掃描二維碼關注慕課網微信公眾號
2015-12-29
不一定,如果是private權限的,就不會,其它情況會,這樣就算不是虛函數也是一樣的。
子類繼承父類,在創建類的時候就會有一個虛函數表的概念,如果子類沒重寫同名函數,子類的虛函數表關于該函數的入口地址就會指向父類的該函數的代碼入口地址
2015-12-29
父類函數如果是虛函數,子類的同名函數(參數也要相同哦)就一定是虛函數,子類的子類也一樣
父類函數不是虛函數,子類同名函數是虛函數,編譯是沒有問題的,如果沒有父類指針指向子類對象的操作也是沒有問題的,但是有父類指針指向子類對象的操作時,操作的函數會是父類的函數,至此都沒有什么問題,但是在父類的指針釋放內存時,系統就會出問題。這時候如果子類還有孫子類,那么子類指針指向孫子類以及重孫子類,都會是覆蓋,也就是調用同名函數的時候,執行的都是實際對象的函數實現。但是父類指針指向孫子類以及重孫子類與指向子類的效果是一樣的。這是我 實測的結果,在delete父類指針時,內存無法釋放,系統就出問題了。
我分析了一下,父類函數不是虛函數,在子類修飾為虛函數,這時候,父類的虛函數表中指向假設0x12345內存地址,子類的虛函數表也應該是指向0x12345,這樣在實例化類的時候,由于父類中該函數是非virtual的,子類的指向也不會變,所以執行結果就是父類與子類的該函數執行父類的函數實現。父類指針指向孫子類的時候,孫子類的虛函數表由于子類聲明為虛函數,就指向假設0x67890內存地址,由于父類的該函數是非virtual的,所以孫子類對象的該函數在虛函數表中要以父類的地址為準,而不會用0x67890覆蓋掉父類的0x12345,所以執行結果仍是父類的實現。這時候子類指針指向孫子類的時候,就與咱學的一樣嘍,執行結果是孫子類的實現。
再來說一下釋放內存出的問題,具體我還真分析不出來,不過如果父類的析構函數是虛析構函數的話,內存的釋放也是沒有問題的,所以我們其它的不管(不管業務是否有業務需要),析構函數最好都加上virtual關鍵字。對于如果有可能被繼承的類,其函數最好都聲明稱虛函數,這樣繼承才有意義,才可以讓你的邏輯在運行時決定使用哪個具體實現(多態)。virtual應該就是為了實現面向對象中的多態才誕生的吧
不用不好意思,學習哪不會說出來咱們一起討論,吃透了,學會了才是我們的目的。