C++:获取类的虚函数表地址
通过类的一个实例来获取类的虚函数地址
环境:Ubuntu + GCC
代码:
test.h
#ifndef _TEST_H_ #define _TEST_H_ #include <iostream> class Single { public: int a; int b; }; class BasicA { public: virtual void Test() { printf("A virtual\n"); int a = 1; long long jj = 20; long j = a + jj; } virtual void Test1() { printf("A virtual 1\n"); printf("jskdlf\n"); } virtual void Test2() { printf("A virtual 2\n"); } }; class BasicB { public: virtual void Test() {}; }; class AB : public BasicA, public BasicB { }; #endif //_TEST_H_
main.cpp
#include <iostream> #include <string> #include "test.h" void HH() { int i = 1; } void Happy(int a, int b) { int c = 1; HH(); int d = 2; d = c; } typedef void (*Func)(); int main(int argc, char** argv) { Happy(1, 2); BasicA a; printf("class A size:%lld, class AB size:%lld\n", sizeof(BasicA), sizeof(AB)); printf("BasicA addr:%p\n", &a); printf("BasicA::Test addr:%p\n", (void*)&BasicA::Test); printf("BasicA::Test addr:%p\n", (void*)&BasicA::Test1); printf("BasicA::Test addr:%p\n", (void*)&BasicA::Test2); printf("address:%llX, int:%llX, long long:%llX\n", &a, *(long long *) * (long long*)&a, *(long long*)&a); printf("a+1:%llX\n", *((long long *) * (long long*)&a + 1)); printf("a+2:%llX\n", *((long long *) * (long long*)&a + 2)); short ui = 12; short* ii = &ui; printf("ii:%llx\n", ii); printf("ii + 1:%llx\n", ii + 1); long long vat = *(long long*)&a;//虚函数表地址 long long* p = (long long*)vat;//指针p指向虚函数表地址 printf("p:%llx, p+1:%llx\n", p, p + 1); a.Test(); Func tt = (Func)(*p);//虚函数表第一个函数的地址 tt(); Func tt1 = (Func)*(p + 1); tt1(); printf("address:%x, int:%x, long long:%x\n", a, &a, *&a); return 0; }
验证结果和 C++虚函数表解析 - 林西索 - 博客园 (cnblogs.com)一致。
PS:在Windows下用Visual Studio验证,结果不同,vs下的编译器使用了不同的规则对代码进行编译。所以对一些C++的标准实现进行验证,最好是在Linux环境下进行。