我正在使用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应该有两个vptrs。
编辑:我检查了vftable的内存内容,因为Serge建议并且确实有三个条目。 由于某种原因,它没有显示在调试器中。
干杯。
不,因为当您创建派生对象时,vtable中的条目将被派生的虚拟函数的地址替换(如果派生的虚函数派生出来的话)。这是在构造对象时完成的,它解释了为什么你不应该在构造函数/析构函数中调用虚函数。 – Borgleader 2014-12-01 15:42:48
为什么要在对象中有两个?一个就足够了,派生类vtable基于基类,为更多虚拟添加额外条目并替换其他条目以指向新实现。 – Deduplicator 2014-12-01 15:44:05
@Borgleader:在ctors和dtors中调用虚函数很好。 – Deduplicator 2014-12-01 15:44:41