因为 C++ 中的所有虚函数都存储在 V-table 中。覆盖发生在虚函数的情况下。 我想问有什么方法可以直接从表中调用虚函数,并且能够确定 V-table 包含哪些函数。
问问题
2851 次
4 回答
19
嗯,其实你可以。我不关心可移植性,但在VS中你可以做到。假设我们使用 VS 构建 32 位代码,对象地址的前 4 个字节是 vtable 地址。通过查看头文件,我们知道 vtable 中方法的顺序。
例子:
class Base
{
public:
virtual void printMessage()
{
std::cout << "Base::printMessage()" << std::endl;
}
};
class Derived : public Base
{
public:
void printMessage()
{
std::cout << "Derived::printMessage()" << std::endl;
}
};
int main(int argc, char* argv[])
{
Derived d;
unsigned int vtblAddress = *(unsigned int*)&d;
typedef void(*pFun)(void*);
pFun printFun = (pFun)(*(unsigned int*)(vtblAddress));
printFun(&d);
return 0;
}
PS我不会问你为什么这样做,但在这里你有一个选择:-)
于 2013-06-14T10:49:02.430 回答
2
标准不保证虚拟功能是使用v-table
. 因此,只有当您确定该编译器使用v-table
- 您才能找到所需的偏移量。
于 2013-06-14T10:33:51.000 回答
2
便携,没有。该语言没有指定虚拟调度是如何实现的,只指定它的行为方式。它不一定使用v-table来实现,除了调用它之外没有办法访问虚函数。
如果您只需要支持一个特定的 ABI,那么您可以使用实现细节以及一些狡猾的指针转换,以与虚拟调度机制相同的方式将对象映射到函数指针。但是你会跨出定义的语言进入不受支持的、不可移植的领域,所以我绝对建议你重新考虑你想做的任何事情。
于 2013-06-14T10:33:58.717 回答
0
一般来说,我会说不,因为 vtable 的确切实现是特定于平台/编译器的。如果您知道平台/编译器如何实现 vtable 和地址,则可以通过确定特定类的 vtable 地址然后添加虚拟方法的偏移量来计算它。
vtable 包含该类的所有虚拟方法。您可以反汇编应用程序以查看它们。
于 2013-06-14T10:35:50.180 回答