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++ 類成員指標C++指標
- 基類指標,子類指標,虛擬函式,override與final指標函式IDE
- c++ 類的函式引用 指標C++函式指標
- python實現多分類評價指標Python指標
- 子父類中函式函式
- 常量引用或指向常量的指標,其所指物件可以是非const物件(C++)指標物件C++
- java關於繼承父類,需要實現父類中的構造方法Java繼承構造方法
- 子類重寫父類的方法@Override的快捷鍵IDE
- 【C++系列】指標物件和物件指標的區別C++指標物件
- 父類和子類物件的獲取值的方式驗證,透過父類屬性的方式獲取不到值,需要使用get方法物件
- java中父類宣告子類例項化Java
- 父類和子類的建構函式問題函式
- 如何理解Python3中的子類和父類?Python
- C++ 類 & 物件C++物件
- 子類擁有父類物件所有的屬性和方法,但無法訪問物件
- 全網最適合入門的物件導向程式設計教程:11 類和物件的Python實現-子類呼叫父類方法-模擬串列埠感測器和主機物件程式設計Python串列埠
- 關於CSS中的定位使用子絕父相(子類絕對位置和父類相對位置)CSS
- c++類和物件C++物件
- C++ 類和物件C++物件
- 【C++】 61_智慧指標類别範本C++指標
- 120 C++中的物件指標C++物件指標
- C++類和物件是什麼?C++類和物件詳解C++物件
- Java子類和父類的初始化執行順序Java
- 子父類中成員變數變數
- C++ 大整數類(BigInteger類)實現C++
- [短文速度-4] new子類是否會例項化父類
- 實現不可變類如何禁止子類化?
- C++,繼承,基類和派生類指標間賦值等知識C++繼承指標賦值
- C++物件導向-類和物件那些你不知道的細節原理C++物件
- 京東獲得jd商品分類API介面(父分類、根分類、子分類)API
- OC底層原理之例項、類物件、元類物件物件
- Go 陣列指標(指向陣列的指標)Go陣列指標
- Hystrix指標視窗實現原理指標
- [C++之旅] 7 C++類和物件C++物件