C 父類指標指向子類物件的實現原理

2021-10-13 18:42:19 字數 1389 閱讀 4788

記得當初阿里面試的時候被問道這個問題,平時自己面對這個方法都習以為常的使用,c++多型和動態繫結不就是這麼實現的嘛,但是還真沒有刻意去關注其中的原理。今天特意看了相關資料,現在分享給大家。

其實這塊我們需要分為兩種情況來考慮,第一種是類繼承(靜態繫結),第二種是父類中包含虛函式(動態繫結)。

2.1 沒有虛函式的繼承

如果以乙個基礎類指標指向乙個派生類物件,那麼經由該指標只能訪問基礎類定義的函式(靜態繫結)。

如果以乙個派生類類指標指向乙個基礎類物件,必須先做強制轉型動作(explicit cast),這種做法很危險,也不符合生活習慣,在程式設計上也會給程式設計師帶來困擾。(一般不會這麼去使用)

如果基礎類和派生類類定義了相同名稱的成員函式,那麼通過物件指標呼叫成員函式時,到底呼叫那個函式要根據指標的原型來確定,而不是根據指標實際指向的物件型別確定。(指標型別是誰就呼叫誰)

這塊我需要說明一下為何基礎類可以指向派生類物件,而派生類不去指向父類物件。

通常來說,子類總是含有一些父類沒有的成員變數,或者方法函式。而子類肯定含有父類所有的成員變數和方法函式。所以用父類指標指向子類時,沒有問題,因為父類有的,子類都有,不會出現非法訪問問題。

但是如果用子類指標指向父類的話,一旦訪問子類特有的方法函式或者成員變數,就會出現非法,因為被子類指標指向的由父類建立的物件,根本沒有要訪問的那些內容,那些是子類特有的,只有用子類初始化物件時才會有。

2.2 包含虛函式的繼承

有虛函式的繼承,那麼父類指標指向子類物件就是我們常見的多型實現,也就是動態繫結。

虛函式就是為了對「如果你以乙個基礎類指標指向乙個衍生類物件,那麼通過該指標,你只能訪問基礎類定義的成員函式」這條規則反其道而行之的設計。

重點:

當然這裡還包括純虛函式,只要是擁有純虛函式的類,就是抽象類,它們是不能夠被例項化的(只能被繼承)。如果乙個繼承類沒有改寫父類中的純虛函式,那麼他也是抽象類,也不能被例項化。抽象類不能被例項化,不過我們可以擁有指向抽象類的指標,以便於操縱各個衍生類。

當定義乙個指向子類例項的父類指標的時候,記憶體中例項化了子類,由於子類繼承了父類,因此記憶體中的子類裡包含父類的所有成員。但由於申明的是父類指標,因此該指標不能夠訪問子類的成員,而只能訪問父類的成員。然而在父類裡可以宣告純虛函式和定義虛函式,使用父類指標訪問**虛函式或純虛函式**的時候,訪問到的是子類裡重寫的函式。當然,對於虛函式,如果子類裡沒有對其重寫的話,仍然訪問到父類裡定義的虛函式。可見虛函式和純虛函式的卻別僅僅在於:純虛函式沒有定義,只有宣告。

區別動態繫結與靜態繫結

參考文獻:

c 父類指標指向子類物件

父類子類指標函式呼叫注意事項 1,如果以乙個基礎類指標指向乙個衍生類物件 派生類物件 那麼經由該指標只能訪問基礎類定義的函式 靜態聯翩 2,如果以乙個衍生類指標指向乙個基礎類物件,必須先做強制轉型動作 explicit cast 這種做法很危險,也不符合生活習慣,在程式設計上也會給程式設計師帶來困擾...

c 父類指標指向子類物件

父類子類指標函式呼叫注意事項 1,如果以乙個基礎類指標指向乙個衍生類物件 派生類物件 那麼經由該指標只能訪問基礎類定義的函式 靜態聯翩 2,如果以乙個衍生類指標指向乙個基礎類物件,必須先做強制轉型動作 explicit cast 這種做法很危險,也不符合生活習慣,在程式設計上也會給程式設計師帶來困擾...

父類指標指向子類物件問題

子類與父類指標呼叫相關注意事項 1,如果以乙個基礎類指標指向乙個衍生類物件 派生類物件 那麼經由該指標只能訪問基礎類定義的函式 靜態聯翩 2,如果以乙個衍生類指標指向乙個基礎類物件,必須先做強制轉型動作 explicit cast 這種做法很危險,也不符合生活習慣,在程式設計上也會給程式設計師帶來困...