Нет таблицы виртуальных функций для абстрактного класса?
Я изучаю таблицы виртуальных функций и их представление, анализируя двоичный файл простой программы, написанной на Visual C++ (с некоторыми оптимизациями).
Несколько дней назад я задал этот вопрос, когда застрял в содержимом таблицы виртуальных методов с идентичным сворачиванием COMDAT.
Теперь я застрял в другом: когда я анализирую класс, мне нужно найти его таблицу виртуальных методов. Я могу сделать это, найдя либо его RTTITypeDescriptor
или же _s_RTTIClassHierarchyDescriptor
найти перекрестную ссылку на него, что должно привести меня к _RTTICompleteObjectLocator
, Когда я нахожу перекрестную ссылку на локатор полного объекта, она записывается непосредственно перед VMT (в основном -1-я запись VMT).
Этот подход работает на некоторых классах (их имена начинаются с C
в моей программе). Тогда есть классы, которые названы с I
в начале, и я могу соединить их с другими классами, начиная с C
- например, есть класс CClass
и это наследует от IClass
, Эти I
-классы, вероятно, служат интерфейсами к C
-классы и, следовательно, они, вероятно, содержат только абстрактные методы.
Путем поиска перекрестной ссылки на дескриптор типа или дескриптор иерархии классов любого из I
-классы я ничего не могу найти - нет полного локатора объектов, который привел бы меня к VMT класса (который должен быть полон ссылок на pure_virtual
вызовите, если я прав насчет всех абстрактных методов в I
-классы и если я правильно понимаю, как выглядит VMT абстрактного класса).
Почему I
-классы не имеют ВМТ? Оптимизировал ли это компилятор, потому что он был бы полон ссылок на pure_virtual
звонить и управлять им по-другому?
1 ответ
Эти абстрактные классы "интерфейсов", вероятно, не нуждаются в написании пользователем кода ни в одном из своих конструкторов и деструкторов (они либо имеют пустое тело и не имеют ctor-init-list, либо просто никогда не определяются пользователем); давайте назовем эти чисто интерфейсные классы.
[Чистый интерфейсный класс: концепция, связанная, но не идентичная Java-интерфейсам, которые (были?) Определены как имеющие нулевой код реализации в любой функции-члене. Но будьте осторожны с аналогиями, поскольку семантика наследования Java-интерфейсов отличается от семантики наследования абстрактных классов C++.]
Это означает, что на практике ни один из используемых объектов никогда не имеет чистого типа интерфейсного класса: ни одно выражение никогда не ссылается на объект с чистым типом интерфейса. Следовательно, vtable никогда не требуется, поэтому vtable, который мог быть сгенерирован во время компиляции, не включен в связанный код (компоновщик может видеть, что символ чистого класса интерфейса vtable не используется).