虚函数的vptr问题
#include <iostream>
using namespace std;
typedef void (*fun)();
class Base
{
int a;
public:
virtual void fun1()
{
cout < < "Base::fun1() " < <endl;
}
virtual void fun2()
{
cout < < "Base::fun2() " < <endl;
}
virtual void fun3()
{
cout < < "Base::fun3() " < <endl;
}
};
class A : public Base
{
int a;
public:
virtual void fun1()
{
cout < < "A::fun1() " < <endl;
}
virtual void fun2()
{
cout < < "A::fun2() " < <endl;
}
};
void *getp (void* p)
{
return (void*)*(unsigned long*)p; // 获取对象内存中的虚函数表地址,即vptr指向的内容
}
fun getfun (Base* obj,unsigned long off)
{
void *vptr = getp(obj);
unsigned char *p = (unsigned char *)vptr;
p += sizeof(void*)*off; // 按字节数加上指针偏移,找到存储虚函数地址的内存位置
return (fun)getp(p); // 去虚函数表中当前位置的内容,即虚函数在内存中的地址
}
我想问一下return (void*)*(unsigned long*)p; 这句话是什么意思,
用unsigned long*是什么意思,还有为什么再要解一次引用,就是中间为什么还有个*号?
对于vptr,我看人家介绍说这是一个数组,数组的元素都是函数指针。
假如这样
Base A;
typdefe void (*fun)( );
取vptr中第一个元素的话下面这里该如何写?麻烦说详细一点,谢谢;
fun pfun=(fun)(??????);
pfun();//这句话会有运行时错误。
[解决办法]
return (void*)*(unsigned long*)p;
p应该是一个指向对象的指针,p指向的内存前四个字节就是指向虚函数表的指针,
*(unsigned long*)p相当于把这个虚函数表的位置值取出来,
[解决办法]
(void*)*(unsigned long*)p;应该是获取该类的首地址,为了避免溢出,使用unsigned long型数据
取vptr中第一个元素:类的首地址+数据成员的偏移量sizeof(int)
[解决办法]
pFun=(fun)*(unsigned long *)p;//这句话运行有问题,为什么?
=======================================================
*(unsigned long *)p;//这只取到了指向 vtable的指针,函数指针在vtable中
fun pfun=(fun)*(unsigned long*)(*(unsigned long *)p);//这样才取得了一个函数指针