我对这里提供的解释有一个疑问http://www.parashift.com/c++-faq/virtual-functions.html#faq-20.4
在示例代码中,函数mycode(Base *p)以p->virt3()的形式调用virt3方法。这里,编译器是如何知道virt3位于vtable的第三个插槽中的呢?它如何比较,与什么比较?
发布于 2011-09-09 21:13:54
The layout of the vtable is specified by the Itanium C++ ABI,后面跟着包括GCC在内的许多编译器。编译器本身并不决定函数指针的去向(尽管我认为它确实决定遵守ABI!)。
虚表中虚函数指针的顺序是类中相应成员函数的声明顺序。
(Example.)
COM -由Visual Studio使用-也按源代码顺序发出vtable指针(尽管我找不到标准文档来证明这一点)。
此外,因为函数名在运行时甚至不存在(而是一个函数指针),所以在编译时vtable的布局并不重要。函数调用转换的工作方式与普通函数调用转换的工作方式相同:编译器已经将函数名映射到其内部机制中的地址。唯一的区别是,这里的映射是到vtable中的一个位置,而不是到实际函数代码的开头。
在某种程度上,这也解决了您对互操作性的担忧。
但是,请记住,这些都是实现机制,C++本身甚至不知道虚拟表是否存在。
发布于 2011-09-09 21:19:43
编译器具有用于分配vtable中的条目的明确定义的算法,使得无论正在处理哪个翻译单元,条目的顺序总是相同的。编译器内部是函数名和它们在vtable中的位置之间的映射,因此编译器可以在函数调用和vtable索引之间进行正确的转换。
因此,重要的是,对具有虚函数的类的定义的更改会导致所有依赖于该类的源文件被重新编译,否则可能会发生不好的事情。
https://stackoverflow.com/questions/7361938
复制相似问题