准确了解对象在内存中的映射方式

时间:2018-10-09 05:09:41

标签: c++ vtable

我阅读了this question和其他一些有关on对象布局的信息,但是我仍然不完全了解它的外观。

这是我的具体问题:

对于每个类(表示如果我有2个超类,我将有2个指针),则虚函数具有1个vtable pointer。它在物体里面在哪里?假设以下内容:class A{void virtual f(){}; int x;};的对象A a的地址是否与a.xa.f的地址相同[ 默认方法,例如C-tor / D-tor 不正确,因为类方法未按照here]

的说明存储在对象中

示例:

    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;
}

1 个答案:

答案 0 :(得分:2)

这纯粹是依赖于实现的(编译器),大多数实现倾向于将vptr插入为第一个元素。由于它是对象地址的第一个元素和开始,因此虚拟函数调用调用的间接调用将更加容易,因为无需进行进一步的偏移量计算即可识别vptr。之前在stackoverflow中提出了类似的问题,发现下面的问题很有用。 Why is vptr stored as the first entry in the memory of a class with virtual functions?