对象的地址 - 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
多重和/或虚拟继承会使这件事变得更加困难。
我试图获取存储在 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
多重和/或虚拟继承会使这件事变得更加困难。