通過肖柯老師答王富濤同學的提問,我想到了通過下面程式讓大家加深對成員函數的理解。成員函數和普通函數不同的是,實際上它還帶有一個特定的參數,就是該類的類型指標。當成員函數被調用時,會預設把類對象的this指標傳遞進去。具體樣本見下面程式
#include <iostream>
using namespace std;
class Base
{
public:
Base(int i):m_i(i)
{}
virtual void f(int i) { cout << "Base::f " << m_i << i << endl; }
private:
int m_i;
};
typedef void(*Fun)(Base*, int i);
int main(int argc, char** agrc)
{
Base b(3);
Base c(4);
Fun pFun = NULL;
cout << "虛函數表地址:" << (int*)(&b) << endl;
cout << "虛函數表 — 第一個函數地址:" << (int*)*(int*)(&b) << endl;
// Invoke the first virtual function
pFun = (Fun)*((int*)*(int*)(&b) + 0);
pFun(&b, 2);
pFun(&c, 2);
return 0;
}
它的輸出結果將是
虛函數表地址:0x22ff34
虛函數表 — 第一個函數地址:0x47bb38
Base::f 32
Base::f 42
實際上記憶體布局相同的情況下,也可以轉換
#include <iostream>
using namespace std;
class Base
{
public:
Base(int i):m_i(i)
{}
virtual void f(int i) { cout << "Base::f " << m_i << i << endl; }
private:
int m_i;
};
class Base2
{
public:
virtual void f() {}
int m_i;
};
typedef void(*Fun)(Base*, int i);
int main(int argc, char** agrc)
{
Base b(3);
Base c(4);
Base2 d;
d.m_i = 5;
Fun pFun = NULL;
cout << "虛函數表地址:" << (int*)(&b) << endl;
cout << "虛函數表 — 第一個函數地址:" << (int*)*(int*)(&b) << endl;
// Invoke the first virtual function
pFun = (Fun)*((int*)*(int*)(&b) + 0);
pFun(&b, 2);
pFun(&c, 2);
pFun((Base*)(&d), 2);
return 0;
}
結果
虛函數表地址:0x22ff34
虛函數表 — 第一個函數地址:0x47bb58
Base::f 32
Base::f 42
Base::f 52
在這裡使用了一些http://blog.csdn.net/haoel/archive/2007/12/18/1948051.aspx該文章的代碼內容,在此表示感謝