论继承情况下直接调用类成员函数地址
作者:佚名; 更新时间:2014-12-05
[论文关键词]C++成员函数 this指针
[论文摘要]分析在继承情况下如何取类的成员函数的地址以及调用该地址。
根据类成员函数的种类不同,在继承下如何取成员函数的地址以及调用该地址的情况也是有所区别的。另外还要注意的是多继承下情况又是如何。类的成员函数和标准的C函数不同,类的成员函数有一个隐藏的指针参数this,它指向一个类的实例。在VC++中,this一般通过ECX寄存器来传递,而普通的成员函数的参数被直接压在堆栈中。this作为参数和其他普通的参数有着本质的不同,即使一个成员函数被一个普通函数的调用,在标准C++中这个成员函数和其他的普通函数的情况不相同,因为没有thiscall这样的关键字来保证它像普通参数一样正常的调用。为此,我分别就以下三种情况作了深入的分析。
一、最简单的单继承,非虚拟函数的情况
class A {
public:
int Af(){ return 1; }
};
class B : public A
{
public:
int Bf(){return 2; }
};
假如我们建立了B类的一个成员函数指针。在这个例子中,Af和Bf都是B的成员函数,所以我们的成员函数指针可以指向Af或者Bf。但是Af需要一个this指针指向B::A(后面我叫它Athis),而Bf需要一个this指针指向B(后面我叫它Bthis)。编译器保证了A类在物理上保存在B类的头部(即B类的起始地址也就是一个A类的一个实例的起始地址),这意味着Athis == Bthis。
二、继承情况下的虚拟函数
class A{
Public:
virtual int fv(){return 11;
}
}; class B : public A {
Public:
virtual int fv(){return 22; }
};
现在A和B都定义了虚函数fv,按C++语法,如果通过指针调用fv,应该发生多态行为。利用下面的代码:
DWORD A_fv,B_fv;
GetMemberFuncAddr_VC6(A_fv,&A::fv);
GetMemberFuncAddr_VC6(B_fv,&B::fv);
A x;B y;
CallMemberFunc(0,A_fv,&x,0); // A::fv
CallMemberFunc(0,B_fv,&x,0); // B::fv
CallMemberFunc(0,A_fv,&y,0); // A::fv
CallMemberFunc(0,B_fv,&y,0); // B::fv
输出如下:
下一篇:论计算机辅助教学与化学教学现代化
热门论文