物件導向語言的主要特點是:封裝性、繼承性、多型性。其中,封裝性使得**模組化,繼承性完成**的復用,多型實現介面的重用。
在c++中,多型性是指具有不同功能的函式用同乙個函式名。即用同乙個函式名,呼叫不同內容的函式。下面主要從多型的實現分析c++中的多型。多型的實現有兩種方式:靜態聯編和動態聯編。
系統在編譯的時候就知道該呼叫哪個函式。也叫做編譯時的多型性,如函式過載。
函式過載:函式名相同,但是他們的引數個數或順序、型別不同。但是不能僅靠返回型別來判斷。
#include "iostream"
using namespace std;
int add(int a, int b);
double add(double a, double b);
void main(void)
我們可以看到,雖然c,d是基類的指標和引用,但是我們可以通過它們訪問其子類的相關函式。這就是針對不同的物件用同樣的函式實現了不同的操作。
關於動態聯編的幾點說明。
(1)、c++規定,動態聯編是在虛函式下實現的。
(2)、動態聯編只能通過指標或引用來操作虛函式,如果用一般類例項來操作虛函式,將按照靜態聯編呼叫虛函式。
這部分從編譯層來分析,多型是怎樣實現的。
編譯器在處理函式過載時,也同時考慮了函式引數的型別和順序。如上面函式過載的例子中,編譯器編譯結果,形如:
add(int a, int b) ------> _add_int_int
add(double a, double b)-------->_add_double_double
所以函式呼叫時,可以根據實參的型別和順序,唯一呼叫相對應的函式。
動態聯編的關鍵在於虛函式。
關鍵字virtual告訴編譯器不應該完成早繫結,應該自動安裝實現繫結所必需的所有機制。
三個步驟實現動態聯編:
(1)、對每個包含虛函式的類,建立乙個表(vtable),用於放置特定類的虛函式的位置。
(2)、在每乙個帶虛函式的類中,編譯器設定指標vpointer(vptr),指向vtable表。
(3)、通過基類指標做虛函式呼叫時(也就是多型呼叫時)編譯器靜態地插入取得vptr,並在vtable中,查詢函式位址**。
下面再具體看乙個例項。
class a
class b
class c:public a,public b
在上面的**中,基類a、b,派生類c的儲存結果為:
派生類c,繼承了基類a、b的特性,同樣也繼承了a、b的vptr和vtable。同時如果在派生類c,如果對函式進行了重寫,則將vtable中相應的函式位址改為派生類的重寫後的函式位址。如圖中紅色部分所示。如果派生類還有自己的虛函式,則將派生類虛函式位址放在基類vtable的表末,如果同時繼續了多個基類,則放在第乙個基類的vtable的表末。如圖中的c::h()。所以派生類物件通過基類的指標或引用訪問虛函式時,通過位址偏移計算,就可以訪問派生類重寫的虛函式,實現動態聯編。
C 中的多型及多型的實現
c 中的多型分為靜多型和動多型兩種情況。靜多型是在編譯時就能確定呼叫函式的型別,包括過載和模板。動多型則是需要在執行時才能確定呼叫哪乙個函式。動多型的產生條件是需要在基類的指標指向派生類的物件,並呼叫派生類的函式。而要想呼叫派生類的函式,那麼基類裡這個函式應寫為虛函式。什麼是虛函式?所謂的虛函式就是...
C 中實現多型的方法
c 實現多型的方法 在c 中,我們常說的多型有編譯時多型與執行時多型兩種。編譯時多型是指由編譯器在編譯的過程中,尋找與之合適的函式,類模板等來生成相關的 而執行是多型我們也常稱之為動態繫結 dynamic binding 這是在執行中由不同的物件來指定的。而這種動態繫結是c 提供的最有用的多型手段。...
C 中的介面實現多型
我們都知道虛方法實現多型,抽象方法實現多型等,我們今天來看看如何使用介面實現多型 1.首先我們先要來了解了解什麼是介面,它存在的意識 01.介面就是為了約束方法的格式 引數和返回值型別 而存在的 02.介面可以實現多繼承,彌補單繼承的缺陷。03.介面可以看成是乙個特殊的抽象類,通過反編譯看原始碼可知...