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

C++ 对象的地址-void*和void**,c++,memory,function-pointers,void-pointers,virtual-functions,C++,Memory,Function Pointers,Void Pointers,Virtual Functions,我试图获取存储在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 ::

我试图获取存储在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;

}
#包括
甲级{
公众:
虚拟整数f(){
返回2;
}
};
int main(){
obj;
void*x=(void**)和obj;
void*y=*((void**)和obj);

std::cout这都是未定义的行为,但以下代码将为您提供该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;
}
多重继承和/或虚拟继承会使这一点变得更加困难


首先:这太疯狂了,尤其是函数调用。不能保证存在任何与成员函数兼容的函数指针类型,无论是虚拟函数还是其他函数。
x
obj
的地址-
(void**)
是不相关的。
y
是“正确”类型的双关语(而且是未定义的行为)。为什么你认为
(void**)和obj
*((void**)和obj)
会是同一个地址?也许我完全误解了。我不明白为什么在那个类型的双关语之后我有一个Y中的vtable地址。这里有很多UB。那是演员std吗?
0x400e88
0x400de4
0x400de4