Идентификатор
В статье про динамический полиморфизм мы затронули вопрос переопределения виртуальных методов. Напомню: если сигнатура виртуального метода наследника будет отличаться от сигнатуры метода родителя, то может нарушиться работа динамического полиморфизма. Если вы хотели переопределить метод, но ошиблись с сигнатурой, то будет создан новый метод. К нему нельзя получить доступ через общий интерфейс!
Может быть вы это специально задумали, может быть вы ошиблись - компилятор не знает, что именно произошло. С его точки зрения и то, и другое - возможное корректное поведение программы, что зависит только от замысла разработчика.
Вот чтобы разделять эти два состояния, переопределяемые виртуальные методы в наследниках нужно отмечать идентификатором
Так мы не только явно выражаем наше намерение для других разработчиков, но и просим компилятор проверить нас. Если по каким-то причинам нарушается правило переопределения родительского виртуального метода, то это приведёт к ошибке компиляции. Мы рекомендуем это делать в строго обязательном порядке!
В противном случае, у компилятора просто нет никаких других критериев, по которым мы можем однозначно утверждать переопределяем мы метод или нет. В живом примере продемонстрировал, что вызов ошибочно переопределенного метода не привел к вызову другой реализации.
Кажется, что проблема надуманная, но практически в любом рабочем проекте это будет запутывать. Этого стараются избегать любой ценой, и про это не упустят возможность спросить на собеседовании :) Тем не менее, иногда такое можно встретить. Например, при просмотре кода 20-летней давности. Идентификатор
Напоминать о необходимости
#cppcore
override
В статье про динамический полиморфизм мы затронули вопрос переопределения виртуальных методов. Напомню: если сигнатура виртуального метода наследника будет отличаться от сигнатуры метода родителя, то может нарушиться работа динамического полиморфизма. Если вы хотели переопределить метод, но ошиблись с сигнатурой, то будет создан новый метод. К нему нельзя получить доступ через общий интерфейс!
Может быть вы это специально задумали, может быть вы ошиблись - компилятор не знает, что именно произошло. С его точки зрения и то, и другое - возможное корректное поведение программы, что зависит только от замысла разработчика.
Вот чтобы разделять эти два состояния, переопределяемые виртуальные методы в наследниках нужно отмечать идентификатором
override
: struct Child : public Parent
{
// Переопределяем виртуальный метод
// Parent::say_name
virtual void say_name() override
};
Так мы не только явно выражаем наше намерение для других разработчиков, но и просим компилятор проверить нас. Если по каким-то причинам нарушается правило переопределения родительского виртуального метода, то это приведёт к ошибке компиляции. Мы рекомендуем это делать в строго обязательном порядке!
В противном случае, у компилятора просто нет никаких других критериев, по которым мы можем однозначно утверждать переопределяем мы метод или нет. В живом примере продемонстрировал, что вызов ошибочно переопределенного метода не привел к вызову другой реализации.
Кажется, что проблема надуманная, но практически в любом рабочем проекте это будет запутывать. Этого стараются избегать любой ценой, и про это не упустят возможность спросить на собеседовании :) Тем не менее, иногда такое можно встретить. Например, при просмотре кода 20-летней давности. Идентификатор
override
появился в C++11, а до этого писали без него. И вот тут придется потратить время, чтобы распутать клубок переопределений. Особенно остро этот вопрос встаёт, когда в наследниках так же не указывается ключевое слово virtual
, что допускается стандартом. В шутку сделал вам игру лабиринт, в которой надо найти неправильно переопределенный метод.Напоминать о необходимости
override
можно с помощью предупреждения:-Wsuggest-override
#cppcore