Задача по C++, которая сложнее, чем кажется
Задачка по C++, с которой мы предлагаем ознакомиться, может показаться сложнее, чем представляется на первый взгляд. Итак, у нас есть 2 простых класса:
class Parent { public: virtual void print(){ std::cout<<"I am the parent class"<<std::endl; } };
class Derived : public Parent { public: virtual void print(int x){ std::cout<<"I am the derived class"<<std::endl; } };
А теперь скажите, что выведут два кусочка кода, написанных ниже:
int main(){ Derived *derived=new Derived; derived->print(); return 0; }
int main(){ Parent *derived = new Derived; derived->print(); return 0; }
Решение
Не думайте, что всё так просто, как может показаться с первого взгляда, ведь решение будет следующим: 1) в 1-м случае мы получим ошибку; 2) в 2-м случае выведется «I am the parent class».
А теперь подробнее. В нашей задаче мы имеем дело с механизмом скрытия имён и перегрузки функций. В 1-м случае внутри производного класса функция переопределит родительские функции вне зависимости от их сигнатуры. В результате, несмотря на то, что в родительском классе есть функция, соответствующая вызываемой внутри
error: no matching function for call to 'Derived::print()'
Но почему же тогда во 2-м случае ошибки не будет, ведь мы тоже используем для вызова
Ключевой момент — поиск имени начинается не с фактического типа объекта, а с объявленного типа объекта (класса, который указан в типе переменной). А переменная derived типа Parent указывает на объект типа Derived, а значит, изначально поиск функции