虚表是属于类的,而不是属于某个具体的对象,一个类只需要一个虚表即可。同一个类的所有对象都使用同一个虚表。
注:intptr_t是值而不是指针类型,在不同的平台保证与地址位数相同,用来存放地址。
#include <iostream>
using std::cout;
using std::endl;
class Base {
public:
virtual void f() { cout << "Base::f" << endl; }
virtual void g() { cout << "Base::g" << endl; }
virtual void h() { cout << "Base::h" << endl; }
};
void printHex(void *data, size_t len) {
for (size_t i=0; i<len; i++) {
printf("%02X ", ((uint8_t*)data)[i]);
}
printf("\n");
}
int main() {
Base b;
printHex(&b, sizeof(b));
void* vptrAddr = &b;
printf("虚函数表指针的地址=对象地址:%p\n", vptrAddr);
intptr_t vptr = *(intptr_t*)(vptrAddr);
printf("虚函数表指针的值:0x%lx\n", vptr);
intptr_t vFuncAddr = *(intptr_t*)(vptr);
for(int i=0; i<3; i++) {
void* funcAddr = (intptr_t*)vFuncAddr + sizeof(intptr_t) * i;
printf("虚函数表第%d个函数地址:%p\n", i+1, funcAddr);
typedef void(*Func)();
((Func)(funcAddr))();
}
return 0;
}
输出如下:
38 50 2C 0E 01 00 00 00
虚函数表指针的地址=对象地址:0x7ffee193d680
虚函数表指针的值:0x10e2c5038
虚函数表第1个函数地址:0x10e2c3f30
Base::f
虚函数表第2个函数地址:0x10e2c3f70
Base::g
虚函数表第3个函数地址:0x10e2c3fb0
Base::h