0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>Теги: c++, программирование на c++, перегрузка функций</p>
1
<p>Теги: c++, программирование на c++, перегрузка функций</p>
2
<p>Задачка по C++, с которой мы предлагаем ознакомиться, может показаться сложнее, чем представляется на первый взгляд. Итак, у нас есть 2 простых класса:</p>
2
<p>Задачка по C++, с которой мы предлагаем ознакомиться, может показаться сложнее, чем представляется на первый взгляд. Итак, у нас есть 2 простых класса:</p>
3
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; } };<p>А теперь скажите, что выведут два кусочка кода, написанных ниже:</p>
3
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; } };<p>А теперь скажите, что выведут два кусочка кода, написанных ниже:</p>
4
int main(){ Derived *derived=new Derived; derived->print(); return 0; } int main(){ Parent *derived = new Derived; derived->print(); return 0; }<h2>Решение</h2>
4
int main(){ Derived *derived=new Derived; derived->print(); return 0; } int main(){ Parent *derived = new Derived; derived->print(); return 0; }<h2>Решение</h2>
5
<p>Не думайте, что всё так просто, как может показаться с первого взгляда, ведь решение будет следующим: 1) в 1-м случае мы получим ошибку; 2) в 2-м случае выведется "I am the parent class".</p>
5
<p>Не думайте, что всё так просто, как может показаться с первого взгляда, ведь решение будет следующим: 1) в 1-м случае мы получим ошибку; 2) в 2-м случае выведется "I am the parent class".</p>
6
<p>А теперь подробнее. В нашей задаче мы имеем дело с<strong>механизмом скрытия имён и перегрузки функций</strong>. В 1-м случае внутри производного класса<strong>функция переопределит родительские функции</strong>вне зависимости от их сигнатуры. В результате, несмотря на то, что в родительском классе есть функция, соответствующая вызываемой внутри main(), компилятор об этом не узнает, поэтому выдаст нам ошибку:</p>
6
<p>А теперь подробнее. В нашей задаче мы имеем дело с<strong>механизмом скрытия имён и перегрузки функций</strong>. В 1-м случае внутри производного класса<strong>функция переопределит родительские функции</strong>вне зависимости от их сигнатуры. В результате, несмотря на то, что в родительском классе есть функция, соответствующая вызываемой внутри main(), компилятор об этом не узнает, поэтому выдаст нам ошибку:</p>
7
error: no matching function for call to 'Derived::print()'<p>Но почему же тогда во 2-м случае ошибки не будет, ведь мы тоже используем для вызова print() объект<strong>Derived</strong>?</p>
7
error: no matching function for call to 'Derived::print()'<p>Но почему же тогда во 2-м случае ошибки не будет, ведь мы тоже используем для вызова print() объект<strong>Derived</strong>?</p>
8
<p><strong>Ключевой момент</strong>- поиск имени начинается не с фактического типа объекта, а с объявленного типа объекта (класса, который указан в типе переменной). А переменная derived типа Parent указывает на объект типа Derived, а значит, изначально поиск функции print() будет выполняться внутри класса Parent. В результате компиляция закончится успешно, а мы получим соответствующий вывод.</p>
8
<p><strong>Ключевой момент</strong>- поиск имени начинается не с фактического типа объекта, а с объявленного типа объекта (класса, который указан в типе переменной). А переменная derived типа Parent указывает на объект типа Derived, а значит, изначально поиск функции print() будет выполняться внутри класса Parent. В результате компиляция закончится успешно, а мы получим соответствующий вывод.</p>
9
<p><a>Источник</a></p>
9
<p><a>Источник</a></p>
10
10