虚拟表如何存储在内存中?他们的布局?
e.g。
class A{
public:
virtual void doSomeWork();
};
class B : public A{
public:
virtual void doSomeWork();
};
内存中A类和B类虚拟表的布局如何?
答案 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)
答案 3 :(得分:3)
答案 4 :(得分:3)
正如其他人已经写过的那样,没有一般方法。 (哎呀,甚至没有人要求虚拟桌子使用。)
但是,我相信它们最有可能被实现为对象中某个偏移量的隐藏指针,该对象引用了一个函数指针表。某些虚函数的地址占用该表中的某些偏移量。通常还有一个指向动态类型std::type_info
对象的指针。
如果您对此类内容感兴趣,请阅读Lippmann's "Inside the C++ Object Model"。但是,除非你的兴趣是学术性的(或者你正在尝试编写C ++编译器 - 但是你不应该问),你不应该打扰。这是一个您不需要知道并且永远不能依赖的实现细节。
答案 5 :(得分:1)
有关Open Watcom课程布局的详细说明,请查看Class Layout笔记