内存中的vtable存储在哪里?

时间:2009-12-15 04:53:13

标签: c++ vtable

内存中的vtable存储在哪里?

6 个答案:

答案 0 :(得分:36)

取决于编译器。

在VC ++中,vtable指针存储在对象分配的开头,在任何成员数据之前。 (假设您的班级至少有一个虚拟成员函数。)

如果你的类与vtable的其他类相乘,那么也可能存在多个vtable指针。

vtable本身会静态分配到您地址空间的某个位置。

然后对象布局看起来像(对于C的实例):

A's VTable ptr
A's member variables.
B's Vtable ptr
B's member variables.
C's member variables.

为heirarchy

class A {
  virtual Ax() {}
  int a, b;
};
class B {
  virtual Bx() {}
  int c, d;
};
class C : public A, public B {
  int foo, bar;
};

答案 1 :(得分:15)

V表?什么vtable? C ++标准没有提到vtable。每个编译器都可以以任何方式实现虚函数。这包括将vtable放在任何地方。

答案 2 :(得分:3)

答案 3 :(得分:2)

vptr通常位于对象的开头( Imperfect C ++ Backyard Hotrodding C++),但标准中并未保证。标准中不保证使用vptrs和vtable。

如果你真的需要知道它在哪里,通常会使用像COM,XPCOM,UNO等那样的东西,这些东西实际上是通过设置一个像vptr这样的东西来设置并设置使用方法它们。

答案 4 :(得分:-1)

包含虚函数的每个实例都有指向虚函数表(vbtl)的虚函数指针,我们只能通过实例找到vtbl。或者您可以使用objdump来读取ELF文件的符号,也许您可​​以找到答案。我希望下面的例子可以帮助你。

#include <iostream>
#include <stdio.h>
typedef void (*fun_pointer)(void);

using namespace std;
class Test
{
 public:
   Test()
    {
     cout<<"Test()."<<endl;
    }
   virtual void print()
    {
     cout<<"Test::Virtual void print()."<<endl;
    }
   virtual void print2()
    {
     cout<<"Test::virtual void print2()."<<endl;
    }
};

class TestDrived:public Test
{
 public:
  TestDrived()
    {
    cout<<"TestDrived()."<<endl;
    }
  virtual void print()
    {
    cout<<"TestDrived::virtual void print()."<<endl;
    }
  virtual void print2()
    {
    cout<<"TestDrived::virtual void print2()."<<endl;
    }
  void GetVtblAddress()
    {
        cout<<"vtbl address:"<<(int*)this<<endl;
    }
  void GetFirstVtblFunctionAddress()
    {
    cout<<"First vbtl function address:"<<(int*)*(int*)this+0 << endl;
    }
  void GetSecondVtblFunctionAddress()
    {
    cout<<"Second vbtl function address:"<<(int*)*(int*)this+1 << endl;
    }
  void CallFirstVtblFunction()
    {
    fun = (fun_pointer)* ( (int*) *(int*)this+0 );
    cout<<"CallFirstVbtlFunction:"<<endl;
    fun();
    }
  void CallSecondVtblFunction()
    {
    fun = (fun_pointer)* ( (int*) *(int*)this+1 );
    cout<<"CallSecondVbtlFunction:"<<endl;
    fun();
    }
private:
    fun_pointer fun;
};



int main()
{
 cout<<"sizeof(int):"<<sizeof(int)<<"sizeof(int*)"<<sizeof(int*)<<endl;
 fun_pointer fun = NULL;
 TestDrived a;
 a.GetVtblAddress();
 a.GetFirstVtblFunctionAddress();
 a.GetSecondVtblFunctionAddress();
 a.CallFirstVtblFunction();
 a.CallSecondVtblFunction();
 return 0;
}

答案 5 :(得分:-2)

Vptr和Vtable存储在数据段......

Vtable就像一个函数指针数组。

Vtable和Vptr在编译时创建,它将在运行时获取内存,vtable条目是虚函数地址。

包含虚函数的类的每个对象都有一个指向虚拟表的额外指针,称为虚拟指针。

每当我们使用object调用虚函数时,首先相应的Vptr将在运行时从Vtable读取函数,最后调用该函数。