【发布时间】:2015-12-17 01:44:34
【问题描述】:
我遇到了一些文章,其中解释了 vptr 和 vtable。 我知道在存储了虚拟函数的类的情况下,对象中的第一个指针是指向 vtable 的 vptr,而 vtable 的数组条目是指向函数的指针,其顺序与它们在类中出现的顺序相同(我已经用我的测试进行了验证程序)。 但我想了解编译器必须使用什么语法才能调用适当的函数。
示例:
class Base
{
virtual void func1()
{
cout << "Called me" << endl;
}
};
int main()
{
Base obj;
Base *ptr;
ptr=&obj;
// void* is not needed. func1 can be accessed directly with obj or ptr using vptr/vtable
void* ptrVoid=ptr;
// I can call the first virtual function in the following way:
void (*firstfunc)()=(void (*)(void))(*(int*)*(int*)ptrVoid);
firstfunc();
}
问题:
1. 但我真正想了解的是编译器如何用vptr 替换对ptr->func1() 的调用?
如果我要模拟通话,我该怎么办?我应该重载-> 运算符吗?但即使这样也无济于事,因为我不知道func1 的真正名称是什么。即使他们说编译器通过vptr访问vtable,它仍然如何知道func1的条目是第一个数组,func2的条目是数组中的第二个元素?函数名称到数组元素之间必须有某种映射关系。
2. 如何模拟它。你能提供编译器用来调用函数func1的实际语法吗(它如何替换ptr->func1())?
【问题讨论】:
-
编译器在内部使用映射(哈希表或查找表或类似的东西)。关于模拟,我曾经写过一个小sn-p,对虚拟调用进行简化模拟,见github.com/vsoftco/snippets/blob/master/virtual_manual.cpp
-
@vsoftco:谢谢。我会复习的。顺便说一句,编译器使用的内部哈希表这个主题是否有任何参考?
-
我不确定,可能有,但我不是这方面的专家。一本好书是amazon.com/Inside-Object-Model-Stanley-Lippman/dp/0201834545
-
@vsoftco 我不同意。 map
(idea) 存在于编译器(在编译时)或解释器中。但是这种技术在运行时不存在于编译成“硬代码”语言、C++ 但 Java 和 C#(JVM 和 .NET)中。方法的位置是固定的,比如有 const integer实现 -
@vsoftco (limit of text) anurag86 问间接邻接运行时,你回答编译器,如果你们都互相理解就OK
标签: c++ virtual-functions vtable vptr