C++父子類之間的轉換
一、常識
隨意開啟一本C++書,基本都會寫著一句話:子物件可以轉化成父物件,父物件不能轉化成子物件。
1.1、子物件可以轉化成父物件
很好理解,其實就是C++多型的體現,父指標可以指向子物件地址,當呼叫父物件裡生命的函式時,會預設呼叫子物件的此“重寫函式”巴拉巴拉巴拉.....
1.2、父物件不可轉化成父物件
存在即道理,這句話其實是想說明,子物件的屬性或者函式大多情況下比父物件更豐富,即父親有的東西一定會傳兒子,兒子有的東西父親不一定有【這個比喻顯然不符合百善孝為先的老百姓,但C++是沒有感情的東西】,如果我們將父物件轉化成了子物件,那麼這個物件勢必會無緣無故多了一些原本不存在的屬性或者函式,如果這些屬性裡包含一些指標或者堆上或者特有的東西,在訪問的時候程式基本就崩了,就出現了程式設計師的老熟人“野指標”、“記憶體洩露”....
用一個例子:
class Parent{ double money; }; class Son : public Parent{ Girl* girl = new Girl; }; main(){ Parent parent; Son* son = &parent; son->girl; }
如上程式碼:
父親只有錢,兒子繼承了父親的錢,並且兒子還有Beautiful Girl,但是此時的實體是父親【只有錢沒有Beautiful Girl】,然後拿著兒子的身份證【介面】去訪問Beautiful Girl,結果GG找不到
二、誤解
2.1、現象
隨意在Bing【強烈抵制Baidu】搜尋C++父子類之間的轉換,發現又能找到很多的方法,那這又是為什麼呢?包括平時都或多或少的用到了父類轉子類的方式如:在Qt介面是將一個按鈕嵌入到Table裡,然後又拿出來強轉成按鈕使用....
2.2、不多bb直接放結論:
嚴格意義上父類是能轉化成子類的,但有限制條件,一旦不注意就會程式崩潰,不建議使用。
2.3、討論之前需要放兩個概念:
Parent* p = new Son;
①、指標物件
p,就是指標,根據多型,可以是父指標也可以是子指標。【一般父指標多得多,多型嘛】
②、物件實體
new Son,也就是new出來或者最後呼叫建構函式的物件【根據父子子父的順口溜,可以知道最後呼叫哪個物件的建構函式,那這個物件就是最終的子類實體】
2.4、適用現象
為什麼我說父類是能轉化成子類的呢,是因為我們直接用父指標來指向子物件,程式碼是能編譯過的,但是不能用父指標去獲取不屬於自己的屬性或記憶體片。
所以當父指標不會跨界去訪問不屬於自己的東西的時候,是沒問題的。
2.5、解釋神奇現象
上面提到平時Qt的一些操作,這個操作雖然用的很多,但是討論這篇文章的時候,同事提出來這個現象,我一時不知如何解釋,感覺多年的C++基礎知識突然崩塌了.....
後來想了想,應該是這樣的步驟:
①、new出子類物件實體,用父指標指向
②、通過父指標將子類物件實體設定到介面上
③、通過父指標從介面上獲取子類物件實體
④、通過static_cast將【父指標指向的】子類物件實體轉成子類
其實整個過程都是子類物件實體,根本沒有父物件實體,所以這裡根本不是父物件轉化成子物件,就是子物件的轉來轉去,只不過用父指標的訪問罷了。