C++父類指標指向子類物件的實現原理
1 前言
記得當初阿里面試的時候被問道這個問題,平時自己面對這個方法都習以為常的使用,C++多型和動態繫結不就是這麼實現的嘛,但是還真沒有刻意去關注其中的原理。今天特意看了相關資料,現在分享給大家。
其實這塊我們需要分為兩種情況來考慮,第一種是類繼承(靜態繫結),第二種是父類中包含虛擬函式(動態繫結)。
2 具體實現
2.1 沒有虛擬函式的繼承
如果以一個基礎類指標指向一個派生類物件,那麼經由該指標只能訪問基礎類定義的函式(靜態繫結)。
如果以一個派生類類指標指向一個基礎類物件,必須先做強制轉型動作(explicit cast),這種做法很危險,也不符合生活習慣,在程式設計上也會給程式設計師帶來困擾。(一般不會這麼去使用)
如果基礎類和派生類類定義了相同名稱的成員函式,那麼通過物件指標呼叫成員函式時,到底呼叫那個函式要根據指標的原型來確定,而不是根據指標實際指向的物件型別確定。(指標型別是誰就呼叫誰)
這塊我需要說明一下為何基礎類可以指向派生類物件,而派生類不去指向父類物件。
通常來說,子類總是含有一些父類沒有的成員變數,或者方法函式。而子類肯定含有父類所有的成員變數和方法函式。所以用父類指標指向子類時,沒有問題,因為父類有的,子類都有,不會出現非法訪問問題。
但是如果用子類指標指向父類的話,一旦訪問子類特有的方法函式或者成員變數,就會出現非法,因為被子類指標指向的由父類建立的物件,根本沒有要訪問的那些內容,那些是子類特有的,只有用子類初始化物件時才會有。
2.2 包含虛擬函式的繼承
有虛擬函式的繼承,那麼父類指標指向子類物件就是我們常見的多型實現,也就是動態繫結。
虛擬函式就是為了對“如果你以一個基礎類指標指向一個衍生類物件,那麼通過該指標,你只能訪問基礎類定義的成員函式”這條規則反其道而行之的設計。
當然這裡還包括純虛擬函式,只要是擁有純虛擬函式的類,就是抽象類,它們是不能夠被例項化的(只能被繼承)。如果一個繼承類沒有改寫父類中的純虛擬函式,那麼他也是抽象類,也不能被例項化。抽象類不能被例項化,不過我們可以擁有指向抽象類的指標,以便於操縱各個衍生類。
2 總結
當定義一個指向子類例項的父類指標的時候,記憶體中例項化了子類,由於子類繼承了父類,因此記憶體中的子類裡包含父類的所有成員。但由於生命的時父類指標,因此該指標不能夠訪問子類的成員,而只能訪問父類的成員。然而在父類裡可以宣告純虛擬函式和定義虛擬函式,使用父類指標訪問虛擬函式或純虛擬函式的時候,訪問到的是子類裡重寫的函式。當然,對於虛擬函式,如果子類裡沒有對其重寫的話,仍然訪問到父類裡定義的虛擬函式。可見虛擬函式和純虛擬函式的卻別僅僅在於:純虛擬函式沒有定義,只有宣告。
參考文獻:
https://www.zhihu.com/question/31345300
http://blog.csdn.net/zhouwei1221q/article/details/47953995
http://www.cnblogs.com/zhangbaochong/p/5380016.html
相關文章
- java中多型的理解——父類引用指向子類物件Java多型物件
- 用指向基類物件的指標輸出資料物件指標
- 鏈式-父類中返回子類物件物件
- Java 中建立子類物件會建立父類物件麼?Java物件
- JAVA 將介面的引用指向實現類的物件Java物件
- C++學習day18之 指向類成員的指標C++指標
- C/C++指向指標的指標C++指標
- 類的繼承_子類繼承父類繼承
- C++ 類成員指標C++指標
- 指向const物件的指標 和 const指標物件指標
- c++ 類的函式引用 指標C++函式指標
- 基類指標,子類指標,虛擬函式,override與final指標函式IDE
- C# 繼承 子類(派生類) 父類(基類)C#繼承
- 第4周專案4-指向學生類的指標指標
- 子父類中函式函式
- c++ auto_ptr類 智慧指標C++指標
- C++智慧指標模板類複習C++指標
- C/C++——指向函式的指標和指向函式的指標的陣列C++函式指標陣列
- python實現多分類評價指標Python指標
- Map中放置類指標並實現呼叫指標
- java關於繼承父類,需要實現父類中的構造方法Java繼承構造方法
- java中父類宣告子類例項化Java
- 父類和子類的建構函式問題函式
- 父類和子類之間的轉換問題
- 指向指標的指標指標
- 父類和子類物件的獲取值的方式驗證,透過父類屬性的方式獲取不到值,需要使用get方法物件
- 子類重寫父類的方法@Override的快捷鍵IDE
- 常量引用或指向常量的指標,其所指物件可以是非const物件(C++)指標物件C++
- 子類擁有父類物件所有的屬性和方法,但無法訪問物件
- C++ 類 & 物件C++物件
- 如何理解Python3中的子類和父類?Python
- 子類繼承父類的建構函式(方法)嗎?繼承函式
- 子類繼承父類(父類和子類裡:塊、靜態塊、構造和方法覆寫)之間呼叫順序繼承
- 關於CSS中的定位使用子絕父相(子類絕對位置和父類相對位置)CSS
- 【C++】 61_智慧指標類别範本C++指標
- 子父類中成員變數變數
- 指向函式的指標函式指標
- 指向陣列的指標陣列指標