Таблица Виртуальных Методов - vtable
HTML-код
- Опубликовано: 7 сен 2024
- Один из способов хранения информации о классе (и соответственно о его объектов) использует таблицу виртуальных методов для хранения ссылок на виртуальные методы (извиняюсь за тавтологию).
Проблема, которую решает этот метод - это невозможность узнать какие будут использоваться виртуальные методы у объекта того или иного класса.
Интересно смотреть, как Иисус рассказывает про программирование (надо было курс называть "Божественное Программирование"))) (сарказм).
Надеюсь, автор не обидится, рассказывает он, конечно, хорошо и очень доходчиво (мне кажется, что у него есть дар учителя). Но выглядит он (и всё это вместе) именно так)
Он помогает слепым новичкам достичь того что уже достигли обычные программисты, позволяя увидеть тем самым новичкам своими глазами разницу и пользу от ранней и поздней типизации. Пустые строки кода вмиг станут наполненными и нести какой-то логический смысл благодаря приобретенному дару. А если серьезней... Хотел лишь выразить благодарность автору за доступное объяснение))
Спасибо за видео, Кхал Дрого
Владимир, у Вас замечательно получается снимать видеоуроки! Желаю Вам успехов!
Это просто замечательно! Хотелось бы больше уроков по C++
Спасибо Вам, долго ломал голову, не мог понять из-за излишней глубины, но Вы всё четко по полочкам разложили. Огромное спасибо
Самое понятное видео из всего что я видел по vtable !)
Спасибо. Для новичков то, что нужно.
Можно попросить объяснение работы try/catch? Не могу найти понятную информацию о том, как C++ делает прерывание стека вызовов, которое непонятно как повторить в языке C. За VTable спасибо, полиморфизм теперь стал ещё более понятным)
Интересные уроки, но есть не точности. Объект не хранит информацию о методах. В нем хранятся только поля. Можно проверить создав класс с кучей методов и посмотреть как его объект в памяти представлен или сделать sizeof. Если в классе нет ни одного поля то размер объекта будет не нулевой, например 1 байт. Если есть хоть одно поле, то размер объекта в не зависимости от количества функций будет равен этому полю. Если полей несколько, то там уже из-за выравнивания размер может варьировать. Если класс имеет виртуальные функции то еще добавляется указатель на vtable.В любом случае подписался, много интересного на канале :)
+ASFlasher О каком языке программирования вы говорите? О каком компиляторе этого языка?
В C++, например, (как я упонянал в этом видео) vtable - это только один из спосовоб реализации виртуальных методов, и реализация виртуальных таблиц тоже решается самим компилятором.
+Vladimir Mozhenkov насчет реализации полиморфизма согласен, есть разные способы, но я не про это. Хранение функций в объекте класса не эффективно, т.к. в таком случае происходил бы большой объем дублирования информации. Намного логичней сделать так как сейчас реализовано во всех мне известных языках. Для класса функция существует в единичном экземпляре, и принимает не явно указатель на объект с которым работает. В С++ через указатель this.
+ASFlasher Я с вами согласен. Я просто про то, что это не то, о чём было это видео. Вы правы, обычные методы не хранятся в каждом объекте индивидуально (по крайней мере не хранятся так ни в одном из известных мне компиляторах).
и что получается это статический объект,...и обращение к одной виртуально странице просходит?
Спасибо!
большая ошибка подменить A на B прямо при старте)))
Объясните, пожалуйста, почему нельзя создавать виртуальные шаблонные функции?
Ни**я еще не понял, но очень интересно!
Если в классах потомках не будет функций с такими же именами как и у предков то таблица виртуальных функций не будет использоваться компилятором, так что-ли?
Все методы наследуются , если паблик. Виртуал для другого
Блин как надоели учителя, которые сами не фига не знают.
Нахватаются по верхам и начинают вещать всякое г.....
Ну так расскажите, в чем ошибки
Грубейшие ошибки:
1) Объект класса не хранит в себе непосредственно информацию об конкретной виртуальной функции. Даже в самом начале создания объекта! (Ошибка на 5:35 минуте ролика).
2) VTBL не удаляет никакой информации из объекта класса! (Дикий бред на 6:03 минуте).
3) Объект класса не содержит в себе VTBL! (Ламмерская сказка 6:29 минута).
Есть еще по мелочи ...
лет 10 назад занимался построением своего языка, пересмотрел кучу
исходников компиляторов и помню что данные базового класса вплотную
лежали с данными производного. (предполагаю по sizeof без выравнивания можно посмотреть) а функции лежали в других местах. да вообще может все черт ногу сломит как компилятор расположить при оптимизации. тут смысл в видео просто для утрированого понимания как работает. может даже при каком-то большем кол-ве функций в объекте вообще хэш функцией искать .хз. как к примеру с большим оператором switch.
блэ) ну нафига путать то? всю жизнь все рисуют A как родитель B как наследник, сиди теперь каждый раз когда видишь B думай что это не то что всегда а наоборот)
Посмотрите UML. Автор использует нотацию UML. Можно считать UML неким стандартом де-факто для рисования классовых диаграмм. Привыкайте, а то будут проблемы на собеседованиях и в работе.
@@knzsoft спасибо за ответ не в тему вопроса)
Остался вопрос: Как при вызове методов компилятор понимает, какую VTABLE нужно использовать? Ему нужно просмотреть все VTABLE?
MrAmmid виртуальная таблица создается для каждого класса(содержащего вирт функции) в иерархии, а каждый объект, при создании, содержит "скрытый" указатель ссылающийся на вирт табл своего класса. Это все упрощенно.
Немного усложняя, если в дочернем классе не переопределена вирт функция базового класса, то вирт таблица этого класса для этого метода просто будет хранить указатель на соответствующую функцию базового класса ( это не фиксировано и зависит от реализации)
При использовании ссылки/указателя базового класса на производный, т.е. (A* p = new B;) можно вызвать у него переопределенный метод (p->f();), проблема здесь одна, компилятор должен заменить эту строку на конкретный адрес вызываемого метода, а таких методов 2. Поэтому подставляется адрес метода из таблицы, (p->pvtb->f();) Да, каждый объект ссылается на свою таблицу, но их внутреннее построение гарантирует одинаковое смещение для переопределенных методов. Т.е. если в памяти A::f() храниться по адресу 10, а B::f() - 20 (утрировано), то во всех таблицах ссылки на эти методы будут располагаться с 8-го байта (сначала в vtable идет тип для RTTI, потом указатель на offset-to-top для множественного наследования, а затем наши методы). И на этапе компиляции p->f() примет вид p->pvtb->8, напротив этой 8-ки в таблице адрес нужного нам метода, в нашем случае 20, так процессор перескочит на 20 байт и продолжит выполнение. Надеюсь не утомил ответом на годовалый вопрос (мало ли кому понадобится)
Я не понимаю, это слишком сложно
Плохо объянил, все намного проще можно подать