内存中的vtable存储在哪里?
答案 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读取函数,最后调用该函数。