关于虚函数的回顾:
1) :虚函数的地址存放于虚函数表之中。运行期多态就是通过虚函数和虚函数表实现的。
2):类的对象内部会有指向类内部的虚表地址的指针。通过这个指针调用虚函数。
3):虚函数的调用会被编译器转换为对虚函数表的访问 。
当虚函数是public的,这个时候实现多态的方式:
class Base {
public:
virtual void f() {
cout << "Base::f" << endl;
}
};
class Derive : public Base{
public:
virtual void f() {
cout<< "derive::f"<<endl;
}
};
int main()
{
Derive d;
Base* b = &d;
b->f();
return 0;
}
程序输出:derive::f。这种调用多态的方式的基类的指针动态绑定子类的对象,在调用虚函数的时候会根据实际初始化的对象的虚表指针对访问对应的虚函数表,以此来调用正确的函数。
当虚函数是private的:
当虚函数是private的,虚函数表的机制依然生效,只是对外部来说不能访问这个接口,我们依然可以用访问虚函数表的形式实现多态:
class Base {
private:
virtual void f() {
cout << "Base::f" << endl;
}
};
class Derive : public Base{
public:
virtual void f() {
cout<< "derive::f"<<endl;
}
};
typedef void(*Fun)(void);
int main()
{
Derive d;
d.f();
Base *b = &d;
Fun pFun = (Fun)*((int*)*(int*)(b)+0);
pFun();
return 0;
}
(int*)(b)是访问b的虚函数表地址
(int*)*(int*)(b)+0是虚函数表第一个函数的地址