单个vtable如何跟踪新的虚拟功能?

时间:2014-12-01 15:40:38

标签: c++ visual-studio virtual-functions vtable vptr

我正在使用VS 2013并试图了解vptr和vftable如何在对象级别工作。所以我有以下课程:

#include<iostream>
using namespace std;

class baseClass
{
public:
    void nonVirtualFunc() {}
    virtual void virtualNonOverriddenFunc() {}
    virtual void virtualOverriddenFunc() {}
};

class derivedClass : public baseClass
{
public:
    virtual void virtualOverriddenFunc() {}
    virtual void derivedClassOnlyVirtualFunc() { cout << "derivedClass" << endl; }
};


int main(int argc, char** argv) {

    derivedClass derivedClassObj2;
    cout << "Size of derivedClassObj: " << sizeof(derivedClassObj2) << endl;

    return 0;
}

这是我在调试时看到的: enter image description here

理论上应该有两个vptrs。一个用于baseClass的vftable,另一个用于derivedClass以跟踪新添加的derivedClassOnlyVirtualFunc()。

但是如你所见,只有一个vptr / vftable。但这种机制运作良好。

我以为在观察窗口中我看不到第二个vptr,所以我打印出了对象的大小。它是4个字节,表示只有一个指针存在。

那么如何使用新添加的虚拟功能?

根据this,应该有两个vpt。

编辑:我检查了像Serge建议的vftable的内存内容,确实有三个条目。 enter image description here 由于某种原因,它没有出现在调试器中。

干杯。

1 个答案:

答案 0 :(得分:1)

vtable实现依赖于编译器。对象的大小(4个字节)表明vtable没有在对象中复制,因为4个字节只是一个指针。我的理解是:

  • 每个类只有一个 vtable (*)(不是每个对象)
  • 每个对象都有一个指向其vtable(其实际类之一)的指针
  • 因为_vfptr是祖先类的一个属性,调试器在祖先类下显示它,因此只显示该类中定义的方法

但是,确实真正的_vtable包含其他虚拟方法的条目...在调试器显示的条目之后!

(*)当您考虑_vfptr数组的内部组织时,事情变得更加困难。事实上,它可以被视为包含祖先类的所有vtable的副本。此处,derivedClass的前2个条目对应baseClass的vtable。但是如果你打开一个内存窗口,并检查_vfptr地址(示例中为0x00d9ba68)的内容,你应该在空条目之前看到第三个条目(至少这是我的MSVC Express 2008展示)。第三个条目对应于函数derivedClassOnlyVirtualFunc,但调试器未显示,如上所述。