Это чисто функция, когда функция переопределяется в C ++.
В C ++ переопределение функции выполняется в соответствии с «сигнатурой» функций-членов:
- unqualifiedname
- точный список параметров в объявлении (исключая неявный
this
) - квалификация
this
неявного параметра
Очевидно, по определению, типпараметра this
не может точно соответствовать , так как по определению тип должен быть указателем на производный класс.
[Замечание о квалификации cv для параметров:
Параметры в объявлении , как видит вызывающая сторона , должны быть точно такими же, то есть после удаления бессмысленных cv-квалификаторов на копиях объектов: это cv-квалификаторы для локальных переменных внутритело функции, и это имеет смысл только в определении функции.
void f(const int i); // takes an int by value; const is meaningless
void f(int i); // redeclaration of the same function
// redeclaration of the same function yet again
void f(const int ci) { // const is meaningful here
ci = 1; // error
}
- примечание конца]
Однако тот же код, НО сдетские классы фуопределение void foo(bool def = true)
Печатает foo Родителя.
Поскольку нет совпадения списков параметров: пустой список параметров совпадает только с пустым списком параметров .
Здесь необходимо заменить аргумент по умолчанию двумя перегруженными функциями, без переадресации на другую:
void foo(bool def); // new function signature
void foo() { // overrides Parent's member
foo(true);
}
При длинном сложном списке параметров легко изменить тип и создать новыйсигнатура функции вместо переопределения виртуальной функции базового класса;также легко ошибиться в использовании заглавных букв или в неправильном написании (подумайте об английском или американском правописании).В общем, неправильное получение имени функции (или любого другого имени: типа, шаблона, переменной ...) вызывает ошибку компиляции, поскольку это имя с небольшим изменением орфографии не было объявлено.Но с необработанным объявлением члена с намерением переопределить объявление базового класса, нет никаких намеков на то, что вы пытались это сделать, и компилятор не предупредит вас (он может предупредить за скрытие объявления базового класса, но это не так.).Явная пометка объявления, предназначенного для переопределения, с помощью ключевого слова virtual
не помогает, введение новой виртуальной функции не является целью.
Это было печальное положение дел после первой версииСтандарт C ++ был формализован.Теперь все по-другому.
Если вы хотите быть уверены, что действительно переопределяете объявление базового класса, теперь вы можете использовать ключевое слово override
:
class Child : public Parent
{
public:
void foo(bool def);
void foo() override {
foo(true);
}
};