C++ 虚拟功能未列在vptr中

C++ 虚拟功能未列在vptr中,c++,visual-studio-2008,C++,Visual Studio 2008,vptr索引应显示所有虚拟函数,但在我的情况下,仅显示3个虚拟函数中的2个 我在下面提供完整的代码和屏幕截图:- ClassHeader.h #include <iostream> using namespace std; // Employee Class class Employee { public : int salary ; Employee(){cout << "Inside CTOR" << endl;} virtual ~Employ

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;}
};
#包括
使用名称空间std;
//雇员阶级
班级员工
{
公众:
国际工资;

Employee(){cout如果您以Employee身份检查该类,因为该类没有Rank(),因此它不会在vtable中显示Rank()。您的屏幕截图显示Employee类的内容

“是的,调试器没有足够的类型信息来告诉您 数组的长度。因此它只显示第一个元素,除非 被推翻。”


这可能是因为Manager是从Employee派生的,但Employee没有Rank方法。因此,当Manager对象调用Rank()时,它永远不需要位于虚拟表中。 我打赌,如果您实例化一个JUnitorManager级别,它将在vtbl中


有关更多说明,请看,但我相信这是正确的原因。

我相信这是因为在Manager继承链中没有可能的秩函数重写器,即使它是虚拟的。换句话说,我认为类必须知道可重写的虚拟函数在哪里才能正确地分派函数调用,这意味着实现必须存储指向虚拟函数的指针。如果没有人可以重写这些函数,则分派中没有歧义,也没有理由在vtable中保留另一个指针

您应该能够通过对您的JUnitorManager实例执行完全相同的练习进行验证:因为我们需要在JUnitorManager实例中维护指向Manager的
Rank
函数的指针,因为我们有一个重写的
Rank
函数,所以我们应该在JUnitorManager的vtable中看到虚拟指针


现在我很好奇。你能帮我们检查一下并报告吗?

我想我们在这里看到的是Visual Studio的一个奇怪的怪癖,我无法解释

我将代码复制到Visual Studio中以查看发生了什么,甚至尝试添加:

JuniorManager*p1=新的JuniorManager();

p1
显示为
JuniorManager
,它是Manager的子类,Manager是Employee的子类

在所有情况下,调试器都完全知道指针变量的确切静态类型和指向的对象的确切动态类型,以及vtable的确切类型和vtable中条目的确切类型。但是,vtable仅作为基类(Employee)的一部分在调试器中可见出于某种原因,只显示基类的已知条目


如果同时显示其余的条目,那就更酷了。

切换链接器属性链接器->优化->对/OPT:NOREF的引用。Visual Studio将删除对未使用(未定义)函数的引用VisualStudio告诉我们,“代码>管理器< /Cuth>代码>雇员E/COD>的基类有2个虚拟函数:析构函数和支付。什么是错误?无效的main())C++允许int main()和int main(int,char **)。我声明的指针指向经理,而不是员工。请查看完整的代码。但是inspector窗口显示的是Employee类。至少从这个意义上说,表的内容是正确的。@SujayGhosh,您声明了
Manager
,但检查了它的基
Employee
,我认为它没有显示为员工pointer.屏幕截图中的类型是Manager。它只是将包含的基类Employee对象显示为Employee。请看我上面的答案,原因是。您的vtable没有Rank as-Rank,因为Manager对象是直接调用,不涉及间接寻址。但是,我确信JUnitorManager在vtable中会有Rank。@perreal,tha这是一句奇怪的话。根据我的实验,调试器有足够的信息来完全填充基类vtable,包括派生类中正确的重写方法——只是不像Sujay希望的那样,首先在派生类中声明的方法。
#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();

}