阅读以下代码
class Base
{
public:
virtual void test()
{
cout<<"Hello World1"<<endl;
}
};
class Derived:public Base
{
public:
virtual void test()
{
cout<<"Hello World2"<<endl;
}
};
// 传入对象指针,返回对象虚函数表中的 test 函数指针
void* get_function_pointer(void* p)
{
// 当前 p指向对象
p = static_cast<void*>(*(static_cast<void**>(p)));
// 当前 p指向类域的虚函数表
p = static_cast<void*>(*(static_cast<void**>(p)));
// 当前 p指向虚函数表中的 test 函数
return p;
}
int main(void){
Base* D = new Derived();
Base* B = new Base();
void (*functionB)() = (void (*)())(get_function_pointer(static_cast<void*>(B)));
functionB(); // 输出 Hello World1
void (*functionD)() = (void (*)())(get_function_pointer(static_cast<void*>(D)));
functionD(); // 输出 Hello World2
}
虚函数表在类域,一个类的不同实例,其虚函数表指针指向的是同一块内存
虚函数表是一块连续内存,每个函数指针占8个字节
直接调用函数指针,编译器会自动做一次寻址,也就是说functionB()和(*functionB)()效果是一样的。
为什么(void (*)()) 可以把Void*转成函数指针,static_cast就会报错?
如果虚函数使用了对象的成员变量,编译器是如何寻找的?(已实测如果确实使用了成员变量,会输出乱码,应该是访问了未知但合法的内存)