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环境下进行。

posted on 2022-08-02 19:12  林西索  阅读(273)  评论(2编辑  收藏  举报