内存中的虚拟表格布局?

时间:2009-08-27 16:11:49

标签: c++ vtable

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

e.g。

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

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

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

6 个答案:

答案 0 :(得分:27)

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

g++ -fdump-class-hierarchy example.h

输出结果为:

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

答案 1 :(得分:11)

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

答案 2 :(得分:6)

内存中的vtable布局完全依赖于编译器;没有“正确”或普遍的方法。

答案 3 :(得分:3)

来自wikipedia

  

C ++标准没有强制要求   究竟动态调度必须如何   实施

所以答案是否定的。 vtable的布局是实现定义的。

答案 4 :(得分:3)

正如其他人已经写过的那样,没有一般方法。 (哎呀,甚至没有人要求虚拟桌子使用。)

但是,我相信它们最有可能被实现为对象中某个偏移量的隐藏指针,该对象引用了一个函数指针表。某些虚函数的地址占用该表中的某些偏移量。通常还有一个指向动态类型std::type_info对象的指针。

如果您对此类内容感兴趣,请阅读Lippmann's "Inside the C++ Object Model"。但是,除非你的兴趣是学术性的(或者你正在尝试编写C ++编译器 - 但是你不应该问),你不应该打扰。这是一个您不需要知道并且永远不能依赖的实现细节。

答案 5 :(得分:1)

有关Open Watcom课程布局的详细说明,请查看Class Layout笔记