对象的地址 - void* 和 void**

Address of the object - void* and void**

我试图获取存储在 y 中的 vtable 地址,但我不明白为什么 x 包含不同的地址。

#include <iostream>
class A {
    public:
        virtual int f() {
            return 2;
        }
};


int main() {
    A obj;
    void* x = (void**)&obj;
    void* y = *((void**)&obj);

    std :: cout << x << std :: endl;
    std :: cout << y << std :: endl;

    void** vtable = (void**)y;
    std :: cout << ((int(*)())(vtable[0]))() << std :: endl;

}

这都是未定义的行为,但以下代码将为您提供该 vtable 地址:

A obj;
void **vtable = * (void ***) &obj;

对vtable的布局做一些假设,我们可以证明是这样的:

#include <iostream>

class A
{
public:
    virtual void f () { }
};


int main() {
    A obj;
    void **vtable = * (void ***) &obj;
    std :: cout << vtable << std :: endl;
    std :: cout << *vtable << std :: endl;
    std :: cout << (void *) &A::f << std :: endl;
}

输出:

0x400e88
0x400de4
0x400de4

多重和/或虚拟继承会使这件事变得更加困难。

Live demo