0

我正在通过分析用 Visual C++ 编写的简单程序的二进制文件(进行了一些优化)来了解虚函数表及其表示。

几天前,当我被困在具有相同 COMDAT 折叠的虚拟方法表内容上时,我问了这个问题

现在我被困在别的事情上:每当我分析一个类时,我都需要找到它的虚拟方法表。我可以通过找到它的RTTITypeDescriptor_s_RTTIClassHierarchyDescriptor,找到它的交叉引用来做到这一点,这应该会引导我到_RTTICompleteObjectLocator. 当我找到对完整对象定位器的交叉引用时,它就写在 VMT 之前(基本上是 VMT 的第 -1 个条目)。

这种方法适用于某些类(它们的名称以C我的程序开头)。然后是类,它们I在开头以 命名,我可以将它们与以开头的其他类配对C——例如,有一个类CClass,它继承自IClass. 这些I-classes 可能充当 -classes 的接口C,因此它们可能只包含抽象方法。

通过搜索对任何 -classes 的 Type Descriptor 或 Class Hierarchy Descriptor 的交叉引用,I我找不到任何东西——没有完整的对象定位器可以引导我到类的 VMT(应该充满pure_virtual调用 if我对I-classes 中的所有抽象方法是正确的,如果我正确理解抽象类的 VMT 是什么样的)。

为什么I-classes没有VMT?编译器是否优化了它,因为它只是充满了pure_virtual调用的引用并以不同的方式管理它?

4

1 回答 1

1

这些“接口”抽象类在其构造函数和析构函数中可能不需要用户编写的代码(它们要么有一个空的主体,没有 ctor-init-list,要么根本就不是用户定义的);我们称这些纯接口类

[纯接口类:概念相关但不等同于在任何成员函数中被定义为具有零实现代码的 Java 接口。但要小心类比,因为 Java 接口继承语义与 C++ 抽象类继承语义不同。]

这意味着实际上没有使用过的对象具有纯接口类类型:没有表达式引用具有纯接口类型的对象。因此,永远不需要 vtable,因此可能在编译期间生成的 vtable 不包含在链接代码中(链接器可以看到未使用纯接口类 vtable 的符号)。

于 2018-11-06T22:36:09.323 回答