Здравствуйте, rg45, Вы писали:
R>Если добавить спецификацю доступа public в с2 ошибка уйдёт, но, опять же, от обоих вызовов — виртуального и невиртуального получим одинаковый эффект.
Тут моя ошибка, нужно было f() описывать в public-части. Давайте считать, что f() доступен для вызова.
Поинт в том, что с точки зрения C++ в конструкторе с4 мы автоматически получаем вызов самой свежей версии f на данный момент.
Это происходит за счет того, что С++ корректно модифицирует таблицу виртуальных методов по мере конструирования класса.
А значит, с формальной точки зрения, виртуальная диспетчеризация работает.
Повторюсь: суть в том, что ожидания неопытного пользователя о поведении виртуальной диспетчеризации в конструкторах/деструкторах, принципиально не совпадают с суровой реальностью стандарта С++