Является ли ключевое слово override просто проверкой переопределенного виртуального метода?

Насколько я понимаю, введение override Ключевое слово в C ++ 11 является не чем иным, как проверкой, чтобы убедиться, что реализуемая функция является overrideиз virtual функция в базовом классе.

Это оно?

185

Решение

Это действительно идея. Дело в том, что вы четко понимаете, что вы имеете в виду, так что в противном случае молчаливая ошибка может быть диагностирована:

struct Base
{
virtual int foo() const;
};

struct Derived : Base
{
virtual int foo()   // whoops!
{
// ...
}
};

Приведенный выше код компилируется, но это не то, что вы, возможно, имели в виду (обратите внимание на отсутствие const). Если бы вы сказали вместо этого, virtual int foo() override, тогда вы получите ошибку компилятора, что ваша функция на самом деле ничего не переопределяет.

213

Другие решения

Цитата из Википедии:

Специальный идентификатор переопределения означает, что компилятор проверит базовый класс (ы), чтобы увидеть, существует ли виртуальная функция с этой точной сигнатурой. А если нет, компилятор выдаст ошибку.

http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final

Редактировать (пытаясь немного улучшить ответ):

Объявление метода как «переопределить» означает, что этот метод предназначен переписать (виртуальный) метод в базовом классе. Переопределяющий метод должен иметь ту же сигнатуру (по крайней мере, для входных параметров), что и метод, который он намеревается переписать.

Почему это необходимо? Хорошо, предотвращены следующие два распространенных случая ошибок:

  1. один опечатки типа в новом методе. Компилятор, не подозревая, что намеревается написать предыдущий метод, просто добавляет его в класс как новый метод. Проблема в том, что старый метод все еще там, новый добавляется просто как перегрузка. В этом случае все вызовы старого метода будут функционировать так же, как и раньше, без каких-либо изменений в поведении (что было бы самой целью переписывания).

  2. забывают объявить метод в суперклассе как «виртуальный», но все же пытаются переписать его в подклассе. Хотя это, очевидно, будет принято, поведение будет не совсем таким, как предполагалось: метод не является виртуальным, поэтому доступ через указатели к суперклассу завершится вызовом старого (суперкласс ‘) метода вместо нового (подкласс’) метода.

Добавление «override» однозначно устраняет это: с помощью этого мы сообщаем компилятору, что ожидаются три вещи:

  1. в суперклассе есть метод с таким же именем
  2. этот метод в суперклассе объявлен как «виртуальный» (то есть предназначен для перезаписи)
  3. метод в суперклассе имеет ту же сигнатуру (input *), что и метод в подклассе (метод перезаписи)

Если какой-либо из них является ложным, то сообщается об ошибке.

* примечание: выходной параметр иногда имеет другой, но связанный тип. Читайте о ковариантных и контравариантных преобразованиях, если интересно.

29

Найденный «переопределение«полезно, когда кто-то обновил сигнатуру виртуального метода базового класса, такую ​​как добавление необязательного параметра, но забыл обновить сигнатуру метода производного класса. В этом случае методы между базовым и производным классом больше не являются полиморфными отношениями. Без объявления переопределения он Трудно найти такого рода ошибки.

24

Да это так. Это проверка, чтобы убедиться, что никто не пытается переопределить и испортить его через испорченную подпись. Вот страница Wiki, которая объясняет это подробно и имеет короткий иллюстративный пример:

http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final

4
По вопросам рекламы [email protected]