我阅读了this question和其他一些有关on对象布局的信息,但是我仍然不完全了解它的外观。
这是我的具体问题:
对于每个类(表示如果我有2个超类,我将有2个指针),则虚函数具有1个vtable pointer
。它在物体里面在哪里?假设以下内容:class A{void virtual f(){}; int x;};
的对象A a
的地址是否与a.x
或a.f
的地址相同[ 默认方法,例如 不正确,因为类方法未按照here] C-tor / D-tor
示例:
class A{
int x;
void f(){}
void virtual g(){}
void virtual h(){}
};
A a;
std::cout << sizeof a; // result = 8
class A{
int x;
void f(){}
void virtual g(){}
};
A a;
std::cout << sizeof a; // result = 8
class A{
int x;
void f(){}
//void virtual g(){}
};
A a;
std::cout << sizeof a; // result = 4
从这些示例中可以看出,当遇到大量(n> 0)个虚函数时,会将指针(在我的32位计算机上为4字节)添加到该对象。会在其他数据成员之前添加它吗?
指出的内容:
A a;
int *p = (int*)&a;
我以此检查了一下。从下面的假设中假设vtable指针总是在其他类成员之前正确吗?
class A{
public:
A(int y){x=y;}
virtual void g(){}
int x;
virtual void f(){}
};
int main ()
{
A a(42);
int *p = (int*)&a;
std::cout << *p << std::endl; // = 4215116 (vtable address?)
std::cout << *(p+1) << std::endl; // = 42
return 0;
}
答案 0 :(得分:2)
这纯粹是依赖于实现的(编译器),大多数实现倾向于将vptr插入为第一个元素。由于它是对象地址的第一个元素和开始,因此虚拟函数调用调用的间接调用将更加容易,因为无需进行进一步的偏移量计算即可识别vptr。之前在stackoverflow中提出了类似的问题,发现下面的问题很有用。 Why is vptr stored as the first entry in the memory of a class with virtual functions?