1

这是投票最多的答案中对VTT的详细描述。但是答案并没有解释为什么top-offsetVTT中有a。

down_cast从我的角度来看,当我们base指向derived指针时,编译器已经知道offset需要在编译时调整(当没有虚拟推导时),所以不需要top_offset在下面的情况下存储a:

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    |         +-----------------------+
      +----------+

top_offset为什么在这种情况下VTT中有a ?我认为 top_offsetandvirtual base offset只需要在虚拟继承中。

4

1 回答 1

2
void *top(B *b) { return dynamic_cast<void *>(b); }

编译器无法在编译时确定正确的偏移量是多少。可以使用空指针、指向完整B对象的指针或指向B子对象的指针调用此函数。这三种情况需要区别对待。vtable 中的偏移量是允许它工作的原因。

于 2018-05-15T07:45:18.170 回答