这是最高投票答案中的detailed description of VTT。但答案并未解释为何VTT中存在top-offset
。
从我的角度来看,当我们down_cast
指向base
指针的derived
时,编译器已经知道编译时需要调整offset
时间(当没有虚拟推导时),因此无需在下面的情况中存储top_offset
:
class A {
public:
int a;
};
class B {
public:
int b;
virtual void w();
};
class C : public A, public B {
public:
int c;
};
在这种情况下,类型C的对象布局如下(数字假定为32位指针):
+-----------------------+
| 0 (top_offset) |//why?
+-----------------------+
c --> +----------+ | ptr to typeinfo for C |
| vtable |-------> +-----------------------+
+----------+ | A::v() |
| a | +-----------------------+
+----------+ | -8 (top_offset) |//why?
| vtable |---+ +-----------------------+
+----------+ | | ptr to typeinfo for C |
| b | +---> +-----------------------+
+----------+ | B::w() |
| c | +-----------------------+
+----------+
为什么在这种情况下VTT中存在top_offset
?我认为top_offset
和virtual base offset
仅在虚拟继承中需要。
答案 0 :(得分:2)
void *top(B *b) { return dynamic_cast<void *>(b); }
编译器无法在编译时确定正确的偏移量是多少。可以使用空指针,指向完整B
对象的指针或指向B
子对象的指针来调用此函数。这三种情况需要区别对待。 vtable中的偏移量允许它工作。