为什么虚拟方法表的大小大于虚拟方法的数量?

问题描述

#include <iostream>

using std::cout;
using std::endl;

class ObjectA {
public:
    ObjectA(int x):value_(x) {}
    virtual void funcA()
    {cout << "ObjectA funcA" << endl;}
    virtual void funcA1()
    {cout << "ObjectA funcA1" << endl;}
private:
    int value_;
};

void printVirtualTable(ObjectA* objA)
{
    typedef void (*funcPtr)();

    funcPtr* vptr = (funcPtr*)(*((uint64_t*)objA));

    while (*vptr) {
        fprintf(stdout,"%p ",*vptr);
        vptr++;
    }
}

int main()
{
    ObjectA* objA = new ObjectA(19);
    printVirtualTable(objA);
    return 0;
}

ObjectA 有 2 个虚方法,所以我认为 vtable 的大小是 2,但是 printVirtualTable 显示 vtable 中有 3 个指针,第一个和第二个指针是 funcAfuncA1,但第三个是什么?

解决方法

我认为您需要将评估条件从 while(vptr) 更改为 while(*vptr)vptr 本身不会为空。

另外,如果你真的调用这些函数,你会看到在第三次调用时程序会崩溃。

这并不意味着您可以依赖此机制。它只是为了回答您的问题 - 第三个指针中没有任何内容。

      void printVirtualTable(ObjectA* objA)
  {
     typedef void(*funcPtr)();

     funcPtr* vptr = (funcPtr*)(*((unsigned int*)objA));

     if (*vptr) {
        (*vptr)();
        fprintf(stdout,"adddress vtable: %p direct address: %p\n",vptr,&objA);
     }
     vptr++;
     if (*vptr) {
        (*vptr)();
        fprintf(stdout,&ObjectA::funcA);
     }
     vptr++;
     if (*vptr) {
        (*vptr)();
        fprintf(stdout,&ObjectA::funcA1);
     }
  }