C 多型實現的機制

2021-06-16 07:04:23 字數 1614 閱讀 5579

1、 多型的概念

從使用方式上簡單的說:就是將父型別的指標指向其子類的例項,然後通過父類指標呼叫子類的成員函式。這種技術可以讓父類的指標有「多種形態」,這是一種泛型技術。所謂泛型技術,說白了就是試圖使用不變的**來實現可變的演算法。比如:模板技術,rtti技術,虛函式技術,要麼是試圖做到在編譯時決議,要麼試圖做到執行時決議。

2、 乙個多型的例子

#include using namespace std;

class animal

; virtual void speak(){};

};class dog:public animal

{public:

void walk()

{ cout<

panimal ->walk();

cout<

結果輸出為:

i am a dog,wang wang

i walk with four legs

i am a chicken,ge ge

i walk with two legs

4 4 4

1、 實現多型的基本原理

在包含虛函式的類中會自動的為其建立乙個虛函式表,這個表裡裝著虛函式的位址。多型就是基於這個虛函式表來實現的。此外,系統也會自動在類裡面新增乙個指標,使其指向這個虛函式表。所以上面3個類用sizeof測其大小,都為4位元組,即為這個自動新增的指標的大小。

上例中的dog類和chicken類中看似沒有虛函式,其實這兩個類中的兩個函式均是虛函式,是從父類繼承下來得屬性。所以加不加virtual效果都是一樣的。

show(new dog());

在呼叫此函式的時候,生成乙個新的dog例項,並用父類的指標指向它。其實在這裡有個型別轉換的過程,new dog()返回的是乙個dog*型別的指標(記為pdog)。這裡傳參的時候使其轉換為父類的指標animal*。

我們先看一下new dog()後生成的例項裡都有些什麼,在這裡,由於沒有成員變數,所以例項裡只存在乙個指標(我們記為pfun), pfun指向乙個虛函式表。虛函式表裡有兩個成員(暫不算結束符),他們分別是dog類中walk和speak函式的位址。如下圖:

然後將此例項賦給父類的指標panimal,使父類指標panimal指向該例項,由於這裡僅僅是型別變換,值沒有發生變化,所以panimal的值是等於pdog的。在呼叫panimal ->speak();時,會發現speak是虛函式,他就會自動到虛函式表中去尋找speak函式的位址。由於panimal實際指向的dog例項,所以他首先發現的是dog例項中的pfun指標,然後找到dog例項的虛函式表,繼而找到dog例項中的speak函式位址。所以panimal ->speak();不會呼叫animal類中的speak函式(除非是將animal例項賦給指標panimal)。同理,若將chicken例項賦給父類指標panimal,進行panimal ->speak();時。將呼叫chicken的speak成員函式。

通過以上的方法就實現了多型的功能,使父類指標具有多種形態。可以根據情況呼叫所有子類的方法。

注意:這裡區分乙個概念,「早期繫結」和「晚期繫結」。對於一般的函式呼叫,在編譯時期就已經確定了函式的位址,即早期繫結。對於虛函式的呼叫,只有在執行時期才能確定函式位址,通過虛函式表確定,即晚期繫結。

C 多型實現機制剖析

物件導向的三大概念 封裝,繼承,多型。封裝突破了c語言函式的概念 繼承實現了 的復用,那麼多型實現了什麼價值呢,簡單理解就是前人寫的 框架 可以呼叫後人寫的 1 什麼是多型?多型性可以簡單的概括為 1個介面,多種方法 在程式執行的過程中才決定呼叫的機制 程式實現上是這樣 通過父類指標呼叫子類的函式,...

C 多型實現機制剖析

物件導向的三大概念 封裝,繼承,多型。封裝突破了c語言函式的概念 繼承實現了 的復用,那麼多型實現了什麼價值呢,簡單理解就是前人寫的 框架 可以呼叫後人寫的 多型性可以簡單的概括為 1個介面,多種方法 在程式執行的過程中才決定呼叫的機制 程式實現上是這樣 通過父類指標呼叫子類的函式,可以讓父類指標有...

C 多型坑點的實現機制

先上兩個簡單的父類子類。class base virtual void func1 int value 1 class derive public base virtual void func1 int value 2 main函式下 derive derive derive pdervie der...