Нет, фактически невозможно переопределить определение в родительском (по крайней мере, когда речь идет о C ++, "переопределение" обычно зарезервировано специально для ссылки на виртуальные функции).Вместо этого, определяя функцию с тем же именем в дочернем классе, просто скрывает функцию в родительском объекте с тем же именем (т. Е. В контексте дочернего объекта, поиск этого имени найдет толькофункция в дочернем элементе, а не родительская).
Если вы хотите (и функции имеют разные подписи), вы также можете получить функции как в родительском, так и в дочернем элементах, обработанные как перегруженные, поэтомуcall будет пытаться вызывать любое совпадение лучше:
struct parent {
void func1(char) {}
};
struct child : public parent {
void func1(long) { }
using parent::func1;
};
Теперь вы получите:
child c;
c.func1('a'); // calls parent::func1
c.func1(123L); // calls child::func1
Это еще один третий тип поведения, отличающийся от наличия виртуальной функции или с функцией в дочернем элементе, которая скрывает функцию в родительском элементе.
В виртуальной функции выбор вызываемой функции основан на динамическом типе, поэтому если у вас есть указатель/ ссылка на базовый класс, вызываемая функция зависит от того, ссылается ли она на объект базового или производного класса.
Когда вы скрываете функцию,вызываемая функция основана на статическом типе, поэтому, если вы вызываете ее через указатель / ссылку на базу, она вызывает базовую функцию, даже если она действительно ссылается на объект производного класса.Однако если вы используете указатель или ссылку на (или непосредственно используете экземпляр) производного класса, он вызовет функцию в производном классе.
С помощью оператора using
вы получите функциюперегрузка, поэтому при вызове функции (в контексте производного класса) вызываемая функция зависит от того, какая сигнатура функции лучше всего подходит для передаваемого вами параметра (параметров).