我正在通过分析用Visual C ++编写的简单程序的二进制文件(具有一些优化功能)来学习虚函数表及其表示。
几天前,我问this question并停留在相同的COMDAT折叠上的虚拟方法表内容中。
现在,我被困在别的东西上:每当我分析一个类时,我都需要找到它的虚拟方法表。我可以通过找到其RTTITypeDescriptor
或_s_RTTIClassHierarchyDescriptor
并在其上找到一个交叉引用来做到这一点,这应该将我引向_RTTICompleteObjectLocator
。当我找到对“完整对象定位器”的交叉引用时,它是在VMT(基本上是VMT的第-1个条目)之前编写的。
此方法适用于某些类(它们的名称在我的程序中以C
开头)。然后有一些类,它们的开头都以I
命名,我可以将它们与以C
开头的其他类配对-例如,有一个类CClass
并且它继承自IClass
。这些I
类可能充当C
类的接口,因此它们可能仅包含抽象方法。
通过搜索任何I
-class的Type Descriptor或Class Hierarchy Descriptor的交叉引用,我找不到任何东西-没有Complete Object Locator会导致我进入该类的VMT(即如果我对pure_virtual
类中的所有抽象方法是正确的,并且如果我正确理解抽象类的VMT是什么样的,则应该充满对I
调用的引用。
为什么I
类没有VMT?编译器是否对它进行了优化,因为它只是充满了对pure_virtual
调用的引用,并以不同的方式对其进行管理?
答案 0 :(得分:0)
这些“接口”抽象类在其构造函数和析构函数中可能不需要用户编写代码(它们具有空的主体,没有ctor-init-list,或者根本就没有用户定义);我们称这些纯接口类。
[纯接口类:与概念相关但与在任何成员函数中定义为零实现代码的Java接口不同(但?)。但是要类推,因为Java接口的继承语义与C ++抽象类的继承语义不同。]
这意味着在实践中没有使用过的对象具有纯接口类类型:没有表达式引用具有纯接口类型的对象。因此,不再需要vtable,因此可能在编译期间生成的vtable不会包含在链接代码中(链接程序可以看到未使用纯接口类vtable的符号)。