C 多型性原理

2021-05-25 06:40:45 字數 1750 閱讀 9553

靜態多型性比較簡單,主要動態多型性比較難理解。

動態多型性有兩個條件:

1、在基類中必須使用虛函式、純虛函式

2、呼叫函式時要使用基類的指標或引用。

只要在基類的成員函式前加上virtual,該成員函式就是虛函式,從基類派生出來的類的同名成員函式,不管前面是否有virtual,同樣是虛函式,在虛函式的實現時,前面不能加virtual。

內聯函式不能是虛函式,因為內聯函式不能在執行時動態確定位置,即使虛函式在類的內部定義,但在編譯的時候仍然看做是非內聯的。

只有類的成員函式才能宣告為虛函式,普通函式不能宣告為虛函式。

靜態成員函式不能是虛函式。

虛函式的原理:

普通函式的處理:

乙個特定的函式都會對映到特定的**,無論時編譯階段還是連線階段,編譯器都能計算出這個函式的位址,呼叫即可。

虛函式的處理:

被呼叫的函式不僅依據呼叫的特定函式,還依據呼叫的物件的種類。通常是由虛函式表(vtable)來實現的。

虛函式表的結構:

它是乙個函式指標表,每乙個表項都指向乙個函式。任何乙個包含虛函式的類都會有這樣一張表。需要注意的是vtable只包含虛函式的指標,沒有函式體。實現上是乙個函式指標的陣列。

虛函式表既有繼承性又有多型性

每個派生類的vtable繼承了它各個基類的vtable,如果基類vtable中包含某一項,則其派生類的vtable中也將包含同樣的一項,但是兩項的值可能不同。如果派生類過載(override)了該項對應的虛函式,則派生類vtable的該項指向過載後的虛函式,沒有過載的話,則沿用基類的值。

每乙個類只有唯一的乙個vtable,不是每個物件都有乙個vtable,每個物件都有乙個指標,這個指標指向該類的vtable(當然,前提是這個類包含虛函式)。

那麼,每個物件只額外增加了乙個指標的大小,一般說來是4位元組。

在類物件的記憶體布局中,首先是該類的vtable指標,然後才是物件資料。

在通過物件指標呼叫乙個虛函式時,編譯器生成的**將先獲取物件類的vtable指標,然後呼叫vtable中對應的項。

對於通過物件指標呼叫的情況,在編譯期間無法確定指標指向的是基類物件還是派生類物件,或者是哪個派生類的物件

但是在執行期間執行到呼叫語句時,這一點已經確定,編譯後的呼叫**能夠根據具體物件獲取正確的vtable,呼叫正確的虛函式,從而實現多型性。

下面是通過基類的指標來呼叫虛函式時,所發生的一切:

step 1:開始執行呼叫 pa->run();(pa為基類指標,這裡能判斷到底是哪個物件)

step 2:取得物件的vtable的指標

step 3:從vtable那裡獲得函式入口的偏移量,即得到要呼叫的函式的指標

step 4:根據vtable的位址找到函式,並呼叫函式。

step 1和step 4對於一般函式是一樣的,虛函式只是多了step 2和step 3。

基類和派生類是共用一表,還是各有各的表(物理上)?

答:基類和派生類是各有各的表,也就是說他們的實體地址是分開的,基類和派生類的虛表的唯一關聯是:當派生類沒有實現基類虛函式的過載時,派生類會直接把自己表的該函式位址值寫為基類的該函式位址值.

開啟**取消

來自:

C 的多型性

c 的多型性 1.多型性的概念 多型性是指用乙個名字定義不同的函式,這函式執行不同但又類似的操作,從而實現 乙個介面,多種方法 多型性的實現與靜態聯編 動態聯編有關。靜態聯編支援的多型性稱為編譯時的多型性,也稱靜態多型性,它是通過函式過載和運算子過載實現的。動態聯編支援的多型性稱為執行時的多型性,也...

有關C 多型性

c 多型性是通過虛函式來實現的,虛函式允許子類重新定義成員函式,而子類重新定義父類的做法稱為覆蓋 override 或者稱為重寫。這裡我覺得要補充,重寫的話可以有兩種,直接重寫成員函式和重寫虛函式,只有重寫了虛函式的才能算作是體現了c 多型性 而過載則是允許有多個同名的函式,而這些函式的引數列表不同...

C 的多型性

type text css rel stylesheet href 是允許將父物件設定成為和乙個或多個它的子物件相等的技術,比如parent child 多型性使得能夠利用同一類 基類 型別的指標來引用不同類的物件,以及根據所引用物件的不同,以不同的方式執行相同的操作.c 中多型更容易理解的概念為允...