#include <stdio.h>
#include <iostream>
struct Animal {
int m_age;
virtual void speak(int c, float d) {
printf("Animal Speak.%d, %f\n", c, d);
}
virtual void run() {
printf("Animal Run.\n");
}
};
struct Cat : Animal {
int life;
void speak(int c, float d) {
printf("Cat Speak. %d, %f\n", c, d);
}
void run() {
printf("Cat Run.\n");
}
};
int main() {
// Cat占用了12个字节,因为第一个字节用来存放虚表的首地址
std::cout << sizeof(Cat) << std::endl;
Cat* cat = new Cat();
unsigned int* vtbptr = *((unsigned int**)cat + 0);
// 通过虚函数表指针调用函数
// 实际上这行代码就相当于 cat->speak(0);
void(__thiscall * f0)(void*, int, float) = (void(__thiscall*)(void*, int, float))vtbptr[0];
f0(nullptr, 0, 3.5f);
// 实际上这行代码就相当于cat->run();
void (__thiscall *f1)() = (void (__thiscall *)())vtbptr[1];
f1();
return 0;
}
直接操作虚函数表是一种高度依赖于特定编译器实现的行为,它不是标准C++的一部分,因此可能在不同的编译器或平台上表现不一致,也可能引入安全和稳定性风险。在实际的应用开发中应该避免这种做法。
不推荐在生产环境中写这种代码装B,行为危险,装B后果自负。
文章评论