Смещение таблицы виртуальных функций - PullRequest
3 голосов
/ 24 января 2010

Я хотел бы спросить вас, от чего зависит смещение таблицы виртуальных функций для класса? Я имею в виду, от того, что я прочитал, зависит, по крайней мере, компилятор, но зависит ли он от класса к классу?

Редактировать: по смещению я имею в виду положение таблицы относительно адреса объекта-владельца.

Редактировать: пример кода:

void **vtable = *((void***)(((char*)object)+offset));

int **ivtable=(int **)vtable;

void* firstFunction = (void*) ivtable[0];

Ответы [ 3 ]

4 голосов
/ 25 января 2010

Существует определенная зависимость от точного класса.

Помните, что C ++ имеет множественное наследование (MI). Следствием MI является то, что один объект может иметь несколько базовых подобъектов. Те, конечно, не могут быть по одному адресу. Это также означает, что некоторые базовые подобъекты на самом деле не начинаются с относительного смещения 0.

Теперь этот MI вносит некоторые сложности в vtables: вы наследуете функции от нескольких баз с разными смещениями. По этой причине довольно распространено использовать разные макеты vtable для классов MI.

В соответствующей заметке MI также означает, что не каждый указатель на объект на самом деле является указателем на начало этого объекта. Вполне вероятно, что указатель SecondBase* на объект Derived смещен на sizeof(FirstBase), то есть указывает где-то посередине объекта Derived.

3 голосов
/ 24 января 2010

Как оказалось, большинство / все компиляторы C ++ на платформе Windows используют одну и ту же компоновку таблицы виртуальных функций. Разработчики технологии COM от Microsoft воспользовались этим фактом, чтобы реализации интерфейсов COM на C ++ можно было компилировать на всех стандартных компиляторах Windows C ++.

У меня нет точного порядка, запомненного, но в основном это сводится к рекурсии левой глубины на графе объектов, так что первый объявленный виртуальный метод слева (самый первый объявлен, если используется множественное наследование ), самый глубокий производный класс - это первый виртуальный метод в таблице. Я не знаю, стандартизировано ли «виртуальное» наследование (используя ключевое слово virtual в объявлении базового класса).

0 голосов
/ 24 января 2010

Это варьируется от класса к классу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...