C++賦值兼容原則


C++賦值兼容原則(派生類對象是基類對象,反之不成立)

 

–基類指針強制轉換成派生類指針


–派生類中重定義基類成員(同名覆蓋)


 

 

假設, 一個基類 "普通人", 一個派生類 "超人".

1) 賦值兼容原則(派生類對象是基類對象,反之不成立)

超人是人吧, 但不是每個人都是超人.
現在我要找一個普通人來干活.
Man* p = new Man; // OK, p指向了一個普通人對象.
Man* p = new SuperMan; // 也OK, 雖然有些大才小用, 但是超人確實可以勝任普通人的工作.
反過來的話.
SuperMan* sp = new Man; // No, 錯誤, 我需要一個超人, 普通人無法勝任..

2) 基類指針強制轉換成派生類指針.

基類指針不可以直接轉換成派生指針.
因為你如果准備讓普通人(基類)去做超人(派生類)的工作, 是非常危險的, 所以語法不允許.
但是, 由(1)我們知道超人有可能隱藏在普通人之間的(指針是Man*, 但實際對象是SuperMan).
在你確切知道他實際上是超人的時候, 那么可以使用"強制轉化", 讓他去做超人的事情.
但是, 如果他真的只是普通人, 那么"強制轉換"的后果是不確定的, 很可能會引發運行錯誤.
Man* p = new SuperMan; // 雖然是Man*, 但實際是SuperMan.
((SuperMan*)p)->Fly(); // "強制轉換"之后調用 Fly(飛行)函數.
Man* p = new Man; // 真的只是普通人.
((SuperMan*)p)->Fly(); // 語法可以通過, 但是運行階段很可能會出現莫名其妙的錯誤.

(3) 派生類中重定義基類成員


成員函數前加virtual表示虛函數, 意味着派生類可能會有自己的特殊實現.
比如說"看"Look這個動作, 普通人只是用肉眼看, 但是超人用紅外線看東西.
class Man{ virtual void Look(){ // 正常人看的代碼.} };
class SuperMan: public Man{ virtual void Look(){ // 紅外線 }};

SuperMan中的Look前面加不加virtual都可以, 意思不會變.
Man* p = new SuperMan;
p->Look() // 紅外線, 雖然用Man*調用函數, 但是由於是虛函數, 會自動定位到SuperMan::Look上。

 


---------------------

 


參考: https://blog.csdn.net/cs494208907/article/details/11920971


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM