C++的多态是通过虚函数来实现的,虚函数机制通过虚函数表来实现动态绑定。
如果一个类本身或者其父类包含虚函数,那么编译器会为类对象的头部额外生成一个指针,用于指向该类维护的虚函数表。虚函数表中维护着来自父类和自身的虚函数。
内存布局示意图:
// 包含虚函数的类
class VirtualBase {
public:
virtual void fun1()
{
std::cout << "VirtualBase fun1" << std::endl;
}
};
class VirtualChild : public VirtualBase {
public:
virtual void fun2()
{
std::cout << "VirtualChild fun2" << std::endl;
}
virtual void fun3()
{
std::cout << "VirtualChild fun3" << std::endl;
}
};
通过虚函数表,调用虚函数
typedef void(*FUNC) ();
void PrintFunc(int* func)
{
FUNC fun = (FUNC) *func;
fun();
}
int main() {
VirtualChild* child = new VirtualChild();
// 将child的地址转换成long long型,因为在64位编译器上面,指针占用8个字节
// child是指向虚函数表的指针的地址
long long* tmp = (long long*) child;
// 解引用,得到虚函数表的地址
long long* vptr = (long long*)(*tmp);
// 虚函数表中第一个方法,继承于父类的虚函数fun1
FUNC fun1 = (FUNC) *vptr;
// 虚函数表中第二个方法
FUNC fun2 = (FUNC) *(vptr + 1);
// 虚函数表中第三个方法
FUNC fun3 = (FUNC) *(vptr + 2);
fun1();
fun2();
fun3();
}
// 输出结果
VirtualBase fun1
VirtualChild fun2
VirtualChild fun3