Задача на перегрузку функций в C++, которая может оказаться сложнее, чем выглядит

Предположим, у нас есть два класса:

Что выведут два следующих куска кода и почему?

Решение

Не все так просто, как кажется на первый взгляд. Если для вас эта задача показалась легкой, то проверьте свои навыки в C++, прочитав решение.

  • В первом случае программа завершится с ошибкой.
  • Во втором случае выведется «Родительский класс».

Мы имеем дело с механизмом перегрузки функций и скрытия имен. В первом случае функция внутри производного класса переопределит родительские функции вне зависимости от их сигнатуры. Поэтому, несмотря на то, что в родительском классе имеется функция, соответствующая вызываемой внутри main(), компилятор об этом не узнает и выдаст ошибку

Почему же во втором случае мы не получаем ошибку, хотя также используем объект Derived для вызова print()?

Ключевым моментом здесь является то, что поиск имени начинается с класса, указанного в типе переменной, а не фактического типа объекта. Переменная derived типа Parent указывает на объект типа Derived, поэтому изначально поиск функции print() будет производиться внутри класса Parent. Вследствие этого компиляция завершается успешно и мы получаем соответствующий вывод.

Источник: Banterly