通过肖柯老师答王富涛同学的提问,我想到了通过下面程序让大家加深对成员函数的理解。成员函数和普通函数不同的是,实际上它还带有一个特定的参数,就是该类的类型指针。当成员函数被调用时,会默认把类对象的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该文章的代码内容,在此表示感谢