内存中的虚拟表格布局?

pan*_*ajt 8 c++ vtable

虚拟表如何存储在内存中?他们的布局?

例如

class A{
    public:
         virtual void doSomeWork();
};

class B : public A{
    public:
         virtual void doSomeWork();
};
Run Code Online (Sandbox Code Playgroud)

内存中A类和B类虚拟表的布局如何?

lin*_*ild 30

对于Linux中的GCC编译器运行:

g++ -fdump-class-hierarchy example.h
Run Code Online (Sandbox Code Playgroud)

输出是:

Vtable for A
A::_ZTV1A: 3u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI1A)
16    (int (*)(...))A::doSomeWork

Class A
   size=8 align=8
   base size=8 base align=8
A (0x7fb76785a4e0) 0 nearly-empty
    vptr=((& A::_ZTV1A) + 16u)

Vtable for B
B::_ZTV1B: 3u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI1B)
16    (int (*)(...))B::doSomeWork

Class B
   size=8 align=8
   base size=8 base align=8
B (0x7fb7678510d0) 0 nearly-empty
    vptr=((& B::_ZTV1B) + 16u)
  A (0x7fb76785a540) 0 nearly-empty
      primary-for B (0x7fb7678510d0)

我还创建了vtable-dumper工具来列出共享对象中虚拟表的内容.使用此工具,您无需编译标头,只需在对象上运行它:

vtable-dumper SHLIB
Run Code Online (Sandbox Code Playgroud)

  • 虽然这个答案没有指出布局没有标准化,但它显然是最好的,因为它显示了一种简单的方法来学习编译器,它的对象布局模型.谢谢! (4认同)
  • 顺便说一句,不要把`(int(*)(...))换成`占位符类型! (2认同)

小智 11

正如其他人所说,这是依赖编译器的,而不是你在日常使用C++时真正需要考虑的事情.但是,如果您只是对这个问题感到好奇,那么您应该阅读Stan Lippman的书" Inside the C++ Object Model".


Dar*_*uid 6

内存中的vtable布局完全依赖于编译器; 没有采取"正确"或普遍的方法.

  • 维基百科(http://en.wikipedia.org/wiki/Virtual_method_table)在描述vtable布局时使用g ++作为示例. (4认同)