Магистерский курс C++ (МФТИ, 2022-2023). Лекция 18. Динамический полиморфизм.

preview_player
Показать описание
Лекции в магистратуре МФТИ по современному C++ на русском языке. Кафедра микропроцессорных технологий.

На этой лекции мы поговорим о неудобной и в чём-то даже неуютной теме -- динамическом полиморфизме в C++. Мы рассмотрим несколько альтернатив, включая CRTP, ручное управление таблицами и инвесрию полиморфизма Мы также углубимся в детали работы статического приведения типов. В конце всё это сойдётся вместе, но станет немного грустно и безнадёжно.

Лектор: Константин Владимиров.
Дата лекции: 1 марта 2023 года.
Съёмка: Марк Гончаров
Звук: Юлий Тарасов.

Timeline
00:00 Мотивация динамического полиморфизма
06:35 Виртуальные функции
12:45 CRTP как альтернатива общему интерфейсу
20:38 Виртуальное копирование и CRTP mixins
28:35 Dreaded diamond и симметрии
39:30 Виртуальное наследование
47:55 Динамическое приведение
53:45 Проблемы виртуальных функций
01:00:20 Задача Дионне и ручное управление таблицами
01:14:00 Инверсия Шона Парента
01:25:55 Завершение и обзор литературы

Errata
* Тут пока пусто
Рекомендации по теме
Комментарии
Автор

Прекрасно@😃!
concept_t это бомба, как все срослось красивой

DrUlrih
Автор

Затронутая тема очень занятна и интересна, спасибо за лекцию.

Решил провести эксперимент и посмотреть, что происходит за кулисами компилятора в момент разрешения рекурсивных шаблонов.

Пусть дан фрагмент кода:
template<typename T, typename U>
struct Base {};

template<typename T, typename... U>
struct Derived : public Base<T, Derived<U...>> {};

Derived<int, double> x; // ok
Derived<int> y; // compile error, предсказуемо

Смотрим insight и наблюдаем, что для переменной x было проинстанцировано:

template<>
struct Derived<int, double> : public Base<int, Derived<double>> {};

Исходя из логики, Derived<double> точно так же должно привести к ошибке нехватки параметров, однако никаких возражений не наблюдается и программа успешно компилируется.

Почему так происходит?

dmitrysavkin
Автор

Благодарю за очередную превосходную лекцию

AlexisVaBel
Автор

Огромное спасибо за лекцию :)

Насчет вектора std::any в 1:24:00 хотелось добавить, что все-таки никаких дополнительных признаков типа хранить не надо, внутри у эни ведь в любом случае лежит std::type_info, так что вполне можно сделать изящный (но гораздо более дорогой, конечно, чем вариантовский) run-time visit по объектам, если завести какую-нибудь мапу type_info на функцию. На cppreference даже пример есть, решение довольно известное =)

allcreater_
Автор

Здравствуйте, Константин. Вы в бакалаврском курсе "Множественное наследование" рассказывали, что dynamic_cast достаточно дорогой и что нужно использовать typeid/static-cast. Если мы создадим ещё одну сущность и она будет наследником, а потом положим в вектор, то ожидается увидеть два числа, а в итоге одно.

Godbolt - 8j8b1j8eG. В каких тогда случаях стоит использовать typeid/static-cast

dmitrydemis
Автор

Спасибо за лекцию!
Был удивлен не увидеть ссылки на P0957, которая замечательно соседствовала бы с AnyAny.

siborgium
Автор

43:39
Такой вопрос. А если база виртуальная не для всех наследников? В ней сразу 2 виртуальных таблицы будет храниться?

danielkeehl
Автор

А где можно почитать в доступном виде информацию, чтобы можно было ответить на вопросы по ассемблеру в начале лекции?

Reishi
Автор

Константин, спасибо за лекцию.
-вижу третью ошибку: не инициализировано поле data ))

alex_s_ciframi
Автор

В любой большой программе рано или поздно появляется, убого реализованный интерпретатор LISP.
(C) не мой

alexloktionoff
Автор

27:56 а у вас тут, случайно, нет ошибки? ведь вы тут, по сути, делаете шаблон виртуальной функции, а это ж ведь стандартом запрещено. или же в случае с deducing this этот запрет как-то иначе работает?

sigasigasiga