LINUX.ORG.RU

История изменений

Исправление mix_mix, (текущая версия) :

тупым копированием со статическим связыванием

Что-то я не распарсил. У нас есть класс A, у него есть vtbl с функциями foo (0x100), bar (0x200) и baz (0x300), в скобках адреса функций в памяти. Вызов a->foo(...) в компайл-тайме раскрывается в (a->(*vptr)[0])(a, ...). Потом у нас есть наследник B, у него есть своя vtbl с функциями foo (0x400), bar (0x200), baz (0x300) и quux (0x500), по адресам поведение уже должно быть понятно — foo замещается, остальные остаются от предка, добавляется новая quux. Вызов b->foo(...) ничем не отличается: (b->(*vptr))[0](b, ...). Ты это имел в виду? Что вся vtbl копируется? Ну так мы гораздо меньше всасываем на производительности, для вызова виртуальной функции нам нужно в худшем случае разыменовать всего три указателя (ссылка на экземпляр класса, vptr и vtbl[n]). Попробуй описать на таком же уровне, как это будет выглядеть в динамике.

Исправление mix_mix, :

тупым копированием со статическим связыванием

Что-то я не распарсил. У нас есть класс A, у него есть vtbl с функциями foo (0x100), bar (0x200) и baz (0x300), в скобках адреса функций в памяти. Вызов a->foo(...) в компайл-тайме раскрывается в (a->(*vptr)[0])(a, ...). Потом у нас есть наследник B, у него есть своя vtbl с функциями foo (0x400), bar (0x200), baz (0x300) и quux (0x500), по адресам поведение уже должно быть понятно. Вызов b->foo(...) ничем не отличается: (b->(*vptr))[0](b, ...). Ты это имел в виду? Что вся vtbl копируется? Ну так мы гораздо меньше всасываем на производительности, для вызова виртуальной функции нам нужно в худшем случае разыменовать всего три указателя (ссылка на экземпляр класса, vptr и vtbl[n]). Попробуй описать на таком же уровне, как это будет выглядеть в динамике.

Исправление mix_mix, :

тупым копированием со статическим связыванием

Что-то я не распарсил. У нас есть класс A, у него есть vtbl с функциями foo (0x100), bar (0x200) и baz (0x300), в скобках адреса функций в памяти. Вызов a->foo(...) в компайл-тайме раскрывается в (a->(*vptr)[0])(a, ...). Потом у нас есть наследник B, у него есть своя vtbl с функциями foo (0x400), bar (0x200), baz (0x300) и quux (0x500), по адресам поведение уже должно быть понятно. Вызов b->foo(...) ничем не отличается: (b->(*vptr))[0](b, ...). Ты это имел в виду? Что вся vtbl копируется? Ну так мы гораздо меньше всасываем на производительности, нам в худшем случае нужно разыменовать три указателя (ссылка на экземпляр класса, vptr и vtbl[n]).

Исходная версия mix_mix, :

тупым копированием со статическим связыванием

Что-то я не распарсил. У нас есть класс A, у него есть vtbl с функциями foo (0x100), bar (0x200) и baz (0x300), в скобках адреса функций в памяти. Вызов a->foo(...) в компайл-тайме раскрывается в (a->(*vptr)[0])(a, ...). Потом у нас есть наследник B, у него есть своя vtbl с функциями foo (0x400), bar (0x200), baz (0x300) и quux (0x500), по адресам поведение уже должно быть понятно. Вызов b->foo(...) ничем не отличается: (b->(*vptr))[0](b, ...).