Не храните вычисленные значения
Пример, у Вас есть таблица "Квадраты" со столбцом "ширина". Никакая потребность сделать столбец "областью", потому что это может быть вычислено через ширину ^ 2
Стандарт 10.3.2 (class.virtual) говорит:
Если виртуальная функция-член vf объявлена в классе Base и в классе Derived, производном прямо или косвенно от Base, a объявляется функция-член vf с тем же именем и тем же списком параметров, что и Base :: vf, тогда Derived :: vf также является виртуальным (независимо от того, объявлен он так или нет) и переопределяет *
[Сноска: функция с тем же именем, но с другим списком параметров (окончание пункта) в качестве виртуальной функции не обязательно является виртуальной и не отменяет. Использование виртуального спецификатора в объявлении замещающей функции допустимо, но является избыточным (имеет пустую семантику). Контроль доступа (пункт class.access) не учитывается при определении переопределения. --- конец foonote]
Быстрый ответ может быть отрицательным, но правильный ответ - да
C ++ не знает о скрытии функций, поэтому переопределение виртуальной функции без виртуальных ключевых слов отмечает, что эта функция тоже виртуальная.
Вы не создаете копию объекта e и не помещаете ее в d. Таким образом, d.foo () следует нормальному полиморфному поведению и вызывает метод производного класса. Метод, объявленный как виртуальный в базовом классе, автоматически становится виртуальным и в производном классе.
Выход («E») ведет себя точно так же, как и следовало ожидать.
Причина: Динамический (то есть во время выполнения) тип этой ссылки - E. Вы выполняете статическое приведение к D, но это, конечно, не меняет фактический тип объекта.
Это сама идея виртуальных методов и динамических диспетчеризации: Вы видите поведение типа, который вы создавали, в данном случае это E.