直接调用类成员函数地址
2010-07-25 20:45:42 来源:WEB开发网四、进一步的讨论
到目前为止,已经讨论了如何取成员函数的地址,然后如何使用这个地址。但是还有些重要的情况没有讨论,我们知道成员函数可分为三种:普通成员函数,静态,虚拟。另外更重要的是,在继承甚至多继承下情况如何。
首先看看最简单的单继承,非虚拟函数的情况。
class tt1
{
public:
void foo1(){ printf("
hi, i am in tt1::foo1
"); }
};
class tt2 : public tt1
{
public:
void foo2(){ printf("
hi, i am in tt2::foo2
"); }
};
注意,tt2中没有定义函数foo1,它的foo1函数是从tt1中继承过来的。这种情况下,我们直接取tt2::foo1的地址行会发生什么?
DWORD tt2_foo1;
tt1 x;
GetMemberFuncAddr_VC6(tt2_foo1,&tt2::foo1);
CallMemberFunc(0,tt2_foo1,&x,0); // tt2::foo1 = tt1::foo1
运行结果表明,一切正常!当我们写下tt2::foo1的时候,编译器知道那实际上是tt1::foo1,因此它会暗中作替换。编译器(VC6)产生的代码如下:
GetMemberFuncAddr_VC6(tt2_foo1,&tt2::foo1); //源代码.
//VC6编译器产生的汇编代码:
push offset @ILT+235(tt1::foo1) (004010f0) //直接用tt1::foo1 替换 tt2::foo1.
...
再看看稍微复杂些的情况,继承情况下的虚拟函数。
class tt1
{
public:
void foo1(){ printf("
hi, i am in tt1::foo1
"); }
virtual void foo3(){ printf("
hi, i am in tt1::foo3
"); }
};
class tt2 : public tt1
{
public:
void foo2(){ printf("
hi, i am in tt2::foo2
"); }
virtual void foo3(){ printf("
hi, i am in tt2::foo3
"); }
};
赞助商链接