c 基礎之 多型

2021-10-05 23:23:02 字數 2418 閱讀 9935

c++物件導向的三大特徵:

虛函式 是在基類中使用關鍵字 virtual 宣告的函式。在派生類中重新定義基類中定義的虛函式時,會告訴編譯器不要靜態鏈結到該函式。

我們想要的是在程式中任意點可以根據所呼叫的物件型別來選擇呼叫的函式,這種操作被稱為動態鏈結,或後期繫結。

多型是由虛函式實現的,而虛函式主要是通過虛函式表(v-table)來實現的。

如果乙個類中包含虛函式(virtual修飾的函式),那麼這個類就會包含一張虛函式表,虛函式表儲存的每一項是乙個虛函式的位址。

這個類的每乙個物件都會包含乙個虛指標(虛指標存在於物件例項位址的最前面,保證虛函式表有最高的效能),這個虛指標指向虛函式表。

注:物件不包含虛函式表,只有虛指標,類才包含虛函式表,派生類會生成乙個相容基類的虛函式表。

下圖是原始基類的物件,可以看到虛指標在位址的最前面,指向基類的虛函式表(假設基類定義了3個虛函式)

假設現在派生類繼承基類,並且重新定義了3個虛函式,派生類會自己產生乙個相容基類虛函式表的屬於自己的虛函式表。

derive class 繼承了 base class 中的三個虛函式,準確的說,是該函式實體的位址被拷貝到 derive類的虛函式表,派生類新增的虛函式置於虛函式表的後面,並按宣告順序存放。

#include

using

namespace std;

classa}

;classb:

public a};

classd:

public a};

classe:

public b};

intmain()

程式的輸出結果是:

a::print

b::print

d::print

e::print

程式中,四個類之間的派生關係如下所示。

每個類都有同名、同參數列的虛函式 print(每個 print 函式宣告時都加了 virtual 關鍵字)。根據多型的規則,對於語句「pa->print()」,由於 print 是虛函式,儘管 pa 是基類 a 的指標,編譯時也不能確定呼叫的是哪個類的 print 函式。當程式執行到該語句時,pa 指向的是哪個類的物件,呼叫的就是哪個類的 print 函式。

例如,程式執行到第 26 行時,pa 指向的是基類物件 a,因此呼叫的就是類 a 的 print 成員函式;執行到第 28 行時,pa 指向的是類 b 的物件,因此呼叫的是類 b 的 print 成員函式;第 30 行也是如此;類 e 是類 a 的間接派生類,因此,執行到第 32 行時,多型規則仍然適用,此時 pa 指向派生類 e 的物件,故呼叫的是類 e 的 print 成員函式。

需要強調的是,編譯器不會分析程式的執行過程。編譯器並沒有通過分析程式上下文,得出在第 28 行 pa 指向的是類 b 的物件,因此第 28 行應該呼叫類 b 的 print 成員函式這樣的結論。

多型的語句呼叫哪個類的成員函式是在執行時才能確定的,編譯時不能確定(具體原理後面會解釋)。因此,多型的函式呼叫語句被稱為是「動態聯編」的,而普通的函式呼叫語句是「靜態聯編」的。

overload(過載):在c++程式中,可以將語義、功能相似的幾個函式用同乙個名字表示,但引數或返回值不同(包括型別、順序不同),即函式過載。

(1)相同的範圍(在同乙個類中);

(2)函式名字相同;

(3)引數不同;

(4)virtual 關鍵字可有可無。

override(重寫):是指派生類函式覆蓋基類函式,特徵是:

(1)不同的範圍(分別位於派生類與基類);

(2)函式名字相同;

(3)引數相同;

(4)基類函式必須有virtual 關鍵字。

注:重寫基類虛函式的時候,會自動轉換這個函式為virtual函式,不管有沒有加virtual,因此重寫的時候不加virtual也是可以的,不過為了易讀性,還是加上比較好。

overwrite(隱藏):隱藏,是指派生類的函式遮蔽了與其同名的基類函式,規則如下:

(1)如果派生類的函式與基類的函式同名,但是引數不同。此時,不論有無virtual關鍵字,基類的函式將被隱藏(注意別與過載混淆)。

(2)如果派生類的函式與基類的函式同名,並且引數也相同,但是基類函式沒有virtual關鍵字。此時,基類的函式被隱藏(注意別與覆蓋混淆)。

C 基礎之多型

多型分為靜態多型和動態多型。靜態多型分為函式過載和泛型程式設計。動態多型是通過虛函式來實現的。靜態多型 叫靜態繫結或早繫結 編譯器在編譯期間完成的,編譯器可以根據函式實參的型別 可能會進行隱式的型別轉換 注意 巨集不是靜態多型,巨集是在預處理階段完成的動態多型 又叫動態繫結或者晚繫結 在程式執行期間...

C 基礎解析之 多型

今天繼續和大家一起 c 我們今天來聊聊c 中物件導向中乙個重要的特性 多型 簡單的一句話解釋多型 相同的方法呼叫可以實現不同的實現方式。通俗的說多型就是不同的表現形式,比如 中國人吃飯用筷子,歐洲以及北美都用刀叉,還有一些另類的人種直接上手,雖然他們的行為方式不同,但是他們有乙個目的就是吃飯!說白了...

c 基礎學習之多型

最近在看一本書 你必須知道的.net 書涵蓋的內容比較多,對於c net平台以往所學的零散東西有了慢慢的總結和新的認識。把一些程式設計客棧基礎的東西記錄於此。先說說多型吧 1.基類繼承式多型 如書中所說,基類繼承式多型的關鍵是繼承體系的設計與實現。書中舉了個簡單的列子 複製 如下 files myf...