vptr索引应该显示所有的虚拟函数,但在我的示例中,仅显示了3个虚拟函数中的2个。
我提供完整的代码和截图如下:
ClassHeader.h
#include <iostream>
using namespace std;
// Employee Class
class Employee
{
public :
int salary ;
Employee(){cout << "Inside CTOR" << endl;}
virtual ~Employee() {cout << "Inside DTOR" << endl;}
virtual void pay(){cout << "Employee" << endl;}
};
// Manager Class
class Manager : public Employee
{
public :
virtual void pay(){cout<< "Manager pay" << endl;}
virtual void Rank(){cout << "Manager Rank" << endl;}
};
// JuniorManager Class
class JuniorManager : public Manager
{
public :
virtual void pay(){cout<< "JuniorManager pay" << endl;}
virtual void Rank(){cout << "JuniorManager Rank" << endl;}
};Main.cpp
#include "ClassHeader.h"
void main()
{
Manager *p = new Manager();
p->pay();
p->Rank();
p = new JuniorManager();
p->Rank();
Employee *pE = dynamic_cast<Employee*>(p);
pE->pay();
}Manager类有两个虚拟函数,pay和Rank,但是只有pay显示在vptr中。
谁能告诉我,为什么Rank没有出现,即使它的虚拟功能。
我使用的是Visual 2008,以及Windows 7 64位上的最新更新。

JuniorManager调试器截图
它也不显示虚拟函数。请看下面的图片。

发布于 2012-02-06 20:13:15
如果以员工身份检查类,因为该类没有Rank(),它将不会在vtable中显示Rank()。屏幕截图显示员工类的内容。
“是的,调试器没有足够的类型信息来判断数组的长度,所以它只显示第一个元素,除非重写。”
http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/23d4e48e-520e-45b4-8c2f-65c11946d75d
发布于 2012-02-06 20:16:04
也许这是因为Manager是从Employee派生出来的,但是Employee没有Rank方法。因此,当Manager对象调用Rank()时,它永远不需要在虚拟表中。我敢打赌,如果你实例化了一个JuniorManager排名将在vtbl中。
要获得更多的澄清,请看Does C++ virtual function call on derived object go through vtable?,但我相信这是正确的原因。
发布于 2012-02-06 20:18:56
我相信这是因为在Manager继承链中没有任何可能的越权者,即使它是虚拟的。换句话说,我认为您的类必须知道可重写的虚拟函数在哪里才能正确地分派函数调用,这意味着实现必须存储指向虚拟函数的指针。如果没有人可以重写函数,那么调度中就没有歧义,也没有理由在vtable中保留另一个指针。
您应该能够通过对您的JuniorManager实例进行完全相同的练习来验证:由于我们需要在JuniorManager实例中维护指向Manager的Rank函数的指针,因为我们有一个覆盖的Rank函数,所以我们应该在JuniorManager的vtable中看到虚拟指针。
现在我很好奇。你能帮我们查一下并汇报一下吗?
https://stackoverflow.com/questions/9166557
复制相似问题