7

这是vtables上的程序。我对 vtables 和 v-pointers 的理解是否正确。

Class B
{
  public:

  virtual Void Hello()
  {
    cout<<"Hello Base";
  }
};

class D: public B    
{
  public:

  virtual void Hello()
  {
    cout<<"Hello Derived";
  }
};

int main(int argc, char* argv[])
{
  D *d1 = new D();
  D *d2 = new D();
  D *d3 = new D();

  return 0;
}

在我看来,将有两个 vtable,只有一个 vptr。我说得对吗?

4

3 回答 3

13

该标准没有定义虚函数的实际实现方式,只定义了它们的行为方式。因此,您所要求的完全取决于您使用的编译器。


GCC 理论上最有可能创建两个 vtable(一个 forB和一个 for D)和三个 vptr(一个用于每个对象实例d1, d2, d3)。

看看这里:http ://en.wikipedia.org/wiki/Virtual_method_table

于 2014-04-19T12:49:29.180 回答
8

您可能会在编译器文档中找到实现细节。它可能因版本而异,甚至在平台之间也是如此。

对于 Linux 上的 gcc,很可能每个 D 实例都需要它的 vptr 和一个 vtable。

您有 3 个 D 实例:

  • 每个都有它的 vptr -> 3 vptr
  • 每个都指向同一个 vtable。

所以3个vptr和1个vtable(B的+1个vtable,这里没用)。

同样,这是一个实现细节,在您非常简单的情况下,它受编译器优化的影响。

于 2014-04-19T13:08:26.113 回答
5

在一个典型的基于 vtable 的虚拟多态实现中,将有:

  • 每个一个 vtable ,包含该类的虚函数指针和其他元数据;
  • 每个对象一个 vptr ,指向该对象的动态类类型的 vtable。

所以这里将有两个 vtables (for Band D) 和三个 vptrs (in *d1, *d2and *d3)。除非编译器注意到您没有使用这些对象,否则会完全消除它们。

于 2014-04-19T13:43:32.387 回答