測試環境
:win10 64位 vs2013
一些概念:
虛函式:類的成員函式前面加上virtual關鍵字,則此成員函式即為虛函式。
重寫:在子類定義了乙個與父類完全相同的虛函式,則稱子類的虛函式重寫了父類的虛函式。
多型:多型就是多種形態,c++的多型分為靜態多型和動態多型。靜態多型就是過載,因為在編譯期間決定呼叫哪個函式,所以稱為靜態多型;動態多型是通過繼承重寫基類的虛函式實現的多型,因為是在執行期間決定呼叫哪個函式,所以稱為動態多型。
1.單繼承物件模型
#pragma once
#include using namespace std;
class base
virtual void f2()
private:
int _a;
};class derive :public base
virtual void f3()
private:
int _b;
};typedef void(*func) ();
void printvtable(int* vtable)
cout << endl;
}void test1()
單繼承原理:
對於b1: 在構造時,為所有虛函式建立乙個虛表,虛表首位址存在物件b1的首位址中。
對於d1: 在構造時,同樣要建立乙個虛表,由於繼承了父類;所以首先構造父類內成員,然後再構造d1內其他成員,在構造父類後,由於存在重寫f1。所以將d1中f1覆蓋到父類f1位置,以下為測試。
記憶體分布:
執行**發現在監視視窗並沒有顯示d1完整的虛函式位址,開啟記憶體視窗,輸入d1的虛表位址。
上述資料基本符合預期,為了更直觀,將上述虛函式位址列印,如下:
現在在base
裡新增兩個
display
()函式,乙個傳參,乙個不傳,使他們構成過載。
void test2()
檢視反彙編,明顯得出動態多型與靜態在定址時極為不同的方式
b2.f1();;
動態多型,虛表尋找位址
moveax,dword ptr [b2]
;b2位址給
eax
movedx,dword ptr [eax];將
eax指向的內容給
edx
movesi,esp
movecx,dword ptr [b2]
;b2位址給
eax
moveax,dword ptr [edx];將
edx內容給
eax
calleax
cmpesi,esp
call__rtc_checkesp (01b1361h)
b2.display();
;靜態多型,編譯時確定位址
movecx,dword ptr [b2]
callbase::display (01b124eh)
b2.display(1);
push1
b2.display(1);
movecx,dword ptr [b2]
callbase::display (01b10e1h)
2.多重繼承物件模型
#include using namespace std;
class base1
cout << endl;
}void test1()
多重繼承原理:在重多繼承過程中,子類的成員函式重寫(上例f1),如果兩個父類同時包含重寫的函式,將子類的其他虛函式存在優先繼承的虛函式表中(上例先繼承base2)。
記憶體分布:
然後我們可以列印出虛函式位址,如下:
於是我們得到多重繼承模型:
3.菱形虛擬繼承
#include using namespace std;
class a
int _a;
};class b : virtual public a
virtual void f2()
int _b;
};class c : virtual public a
virtual void f2()
int _c;
};class d : public b, public c
virtual void f3()
int _d;
};void test1()
通過檢視記憶體分配和列印每個虛表內函式位址,畫出如下d1
模型圖,
由於虛繼承將a構造的物件,放置在了最下面,然後有一虛基表指向此處,以後可以訪問。
虛函式與多型
前三者為靜態繫結,虛函式為動態繫結 動態繫結 只有通過基類指標或引用呼叫虛函式才能引發動態繫結 虛函式不能被宣告為靜態 include using namespace std class base virtual void fun2 void fun3 class derived public ba...
虛函式與多型
多型性 呼叫同乙個函式名,可以根據需要實現不同的功能。虛函式 可以在程式執行時通過呼叫相同的函式名而實現不同功能的函式稱為虛函式。編譯時的多型性 函式過載 執行時的多型性 虛函式 執行時的多型性是指在程式執行之前,根據函式名和引數無法確定應該呼叫哪乙個函式,必須在程式的執行過程中,根據具體的執 況來...
虛函式與多型
多型性 c 支援兩種多型性 編譯時多型性,執行時多型性 虛函式 派生類可以不顯式地用virtual宣告虛函式,這時系統就會用以下規則來判斷派生類的乙個函式成員是不是虛函式 一般習慣於在派生類的函式中也使用virtual關鍵字,以增加程式的可讀性 該函式是否與基類的虛函式有相同的名稱 引數個數及對應引...