我正在使用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;
}
这是我在调试时看到的:
理论上应该有两个vptrs。一个用于baseClass的vftable,另一个用于derivedClass以跟踪新添加的derivedClassOnlyVirtualFunc()。
但是如你所见,只有一个vptr / vftable。但这种机制运作良好。
我以为在观察窗口中我看不到第二个vptr,所以我打印出了对象的大小。它是4个字节,表示只有一个指针存在。
那么如何使用新添加的虚拟功能?
根据this,应该有两个vpt。
编辑:我检查了像Serge建议的vftable的内存内容,确实有三个条目。 由于某种原因,它没有出现在调试器中。干杯。
答案 0 :(得分:1)
vtable实现依赖于编译器。对象的大小(4个字节)表明vtable没有在对象中复制,因为4个字节只是一个指针。我的理解是:
_vfptr
是祖先类的一个属性,调试器在祖先类下显示它,因此只显示该类中定义的方法但是,确实真正的_vtable包含其他虚拟方法的条目...在调试器显示的条目之后!
(*)当您考虑_vfptr
数组的内部组织时,事情变得更加困难。事实上,它可以被视为包含祖先类的所有vtable的副本。此处,derivedClass
的前2个条目对应baseClass
的vtable。但是如果你打开一个内存窗口,并检查_vfptr地址(示例中为0x00d9ba68
)的内容,你应该在空条目之前看到第三个条目(至少这是我的MSVC Express 2008展示)。第三个条目对应于函数derivedClassOnlyVirtualFunc
,但调试器未显示,如上所述。