多型的相關總結

2021-06-26 06:49:42 字數 1513 閱讀 8599

當不同的物件呼叫相同的名稱的成員函式的,可能引起不同的行為(即執行不同的**)。這種現象就稱為多型。將函式呼叫鏈結相應函式體的**過程稱為函式聯編。分為動態聯編和靜態聯編。

靜態聯編,不同的類可以有相同名稱的函式,這種在編譯期間進行的聯編稱為靜態聯編。靜態聯編所支援的多型性就是編譯時多型性。函式過載就屬於編譯時多型性。對於非虛成員來說,系統在編譯時,根據傳遞的引數、返回的型別等資訊決定實現何種操作。

在動態聯編中,在程式執行時才能確定呼叫哪個函式。動態聯編所支援的多型性稱為執行時多型性。在c++中,只有虛函式才可能是動態聯編。可以通過類的虛函式和建立派生類,然後在派生類中重新定義虛函式,實現具有執行時的多型性。

要獲得動態繫結,必須通過基類的引用或指標呼叫虛成員。當我們這樣做時,編譯器將在基類中查詢函式,假定找到了這個函式,編譯器就檢查實參是否與形參匹配。

虛函式必須在基類和派生類中擁有同一原型。如果基類成員與派生類成員接受的實參不同,就沒有沒辦法通過基類型別的引用或指標呼叫派生類函式。例如:

class base ;

class d1: public base ;

class d2: public d1 ;

d1中的fcn版本沒有重定義base的虛函式fcn,相反,它遮蔽了基類的fcn。結果d1有兩個名為fcn的函式:類從base繼承了乙個名為fcn的虛函式,類又定義了自己的名為fcn的非虛成員,該函式接受乙個int形參。但是,從base繼承的虛函式不能通過d1物件呼叫,因為該函式被fcn(int)的定義遮蔽了。

類d2重定義了它繼承的兩個函式,它重定義了base中定義的fcn的原始版本並重定義了d1中的非虛版本。

通過基類型別的引用或指標呼叫函式時,編譯器將在基類中查詢該函式而忽略派生類:

base bobj;

d1 d1obj;

d2 d2obj;

base* bp;

bp->fcn(); //呼叫base::fcn 

bp = &d1obj;

bp->fcn(); //呼叫base::fcn 

bp = &d2obj; 

bp->fcn(); //呼叫d2::fcn

通過在base中查詢fcn來確定三個類的呼叫,所以這些呼叫是合法的。另外,因為fcn是虛函式,所以編譯器會生成**,在執行時基於引用或指標所繫結的物件的實際型別進行呼叫。

理解c++中繼承層次的關鍵在於理解如何確定函式呼叫,確定函式呼叫遵循以下四個步驟:

(1)首先確定進行函式呼叫的物件、引用或指標的靜態型別。

(2)在該類中查詢函式,如果找不到,就在直接基類中查詢,如此循著類的繼承鏈往上找,直到找到該函式或者查詢完最後乙個類。如果不能在類或其相關基類中找到該名字,則呼叫是錯誤的。

(3)一旦找到該名字,則進行常規型別檢查。檢視如果給定找到的定義,該函式呼叫是否合法。

(4)假定函式呼叫合法,編譯器就會生成**。如果函式是虛函式且通過引用或指標呼叫,則編譯器生成**以確定根據物件的動態型別執行哪個函式版本,否則編譯器生成**直接執行。

多型的總結

什麼時候用虛方法來實現多型 什麼時候用抽象類來實現多型 什麼時候用介面來實現多型 抽象類就是 在提供的幾個類當中能抽象出乙個父類 並且父類當中能寫出這些子類共有的方法 還不知道如何去寫這個方法 就用抽象類 反之 抽象出來的方法可以寫 我還需要建立乙個父類物件就用虛方法 介面就是 這幾個類根本找不出乙...

C 多型相關

當通過指標訪問類的成員函式時 如果該函式是非虛函式,那麼編譯器會根據指標的型別找到該函式 也就是說,指標是哪個類的型別就呼叫哪個類的函式。如果該函式是虛函式,並且派生類有同名的函式遮蔽它,那麼編譯器會根據指標的指向找到該函式 也就是說,指標指向的物件屬於哪個類就呼叫哪個類的函式。這就是多型。編譯器之...

繼承 多型的相關知識

一 繼承 在php中,使用extends實現繼承。作用 如果我們不使用繼承,就要寫很多重複的 二 繼承的構造方法 1 子類繼承父類時,子類沒有構造方法,例項化子類物件時,會執行父類的構造方法。子類如果有自己的構造方法,例項化子類物件時,只會自動執行子類自己的構造方法。2 子類的構造方法有兩個引數,所...