Насколько я понимаю, введение override
ключевого слова в C ++ 11 является не чем иным, как проверкой, чтобы убедиться, что реализуемая функция override
является virtual
функцией функции в базовом классе.
Это оно?
Насколько я понимаю, введение override
ключевого слова в C ++ 11 является не чем иным, как проверкой, чтобы убедиться, что реализуемая функция override
является virtual
функцией функции в базовом классе.
Это оно?
Ответы:
Это действительно идея. Дело в том, что вы четко понимаете, что вы имеете в виду, так что в противном случае молчаливая ошибка может быть диагностирована:
struct Base
{
virtual int foo() const;
};
struct Derived : Base
{
virtual int foo() // whoops!
{
// ...
}
};
Приведенный выше код компилируется, но это не то, что вы, возможно, имели в виду (обратите внимание на отсутствие const
). Если бы вы сказали вместо этого, virtual int foo() override
то вы получите ошибку компилятора, что ваша функция фактически ничего не переопределяет.
override
функция «исправляет» это; Вы должны помнить, чтобы использовать его, так же, как вы должны были помнить, чтобы написать const
;)
explicit
определения классов не попали в C ++ 11. Да.
explicit
делать определение класса? Никогда не слышал об этом вообще.
override
когда кто-то намеревается это сделать) более вероятно, чем запоминание угловых случаев, т. е. нет универсальности в копировании функций различных прототипов, только нарушения, такие как отсутствие const
или запись char
вместо int
и т. д.
override
спецификатора упоминается в этом ответе , который является скорее футуристическим, чем немедленным. Ответ предполагает , что, сохранить override
с virtual
методом. В будущем, когда кто-то по ошибке меняет подпись, его полезность начинает
Цитата из Википедии:
Специальный идентификатор переопределения означает, что компилятор проверит базовый класс (ы), чтобы увидеть, существует ли виртуальная функция с этой точной сигнатурой. А если нет, компилятор выдаст ошибку.
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
Редактировать (пытаясь немного улучшить ответ):
Объявление метода как «override» означает, что этот метод предназначен для перезаписи (виртуального) метода в базовом классе. Переопределяющий метод должен иметь ту же сигнатуру (по крайней мере для входных параметров), что и метод, который он намеревается переписать.
Почему это необходимо? Хорошо, предотвращены следующие два распространенных случая ошибок:
один опечатки типа в новом методе. Компилятор, не подозревая, что намеревается написать предыдущий метод, просто добавляет его в класс как новый метод. Проблема в том, что старый метод все еще там, новый добавляется просто как перегрузка. В этом случае все вызовы старого метода будут функционировать так же, как и раньше, без каких-либо изменений в поведении (что было бы самой целью переписывания).
забывают объявить метод в суперклассе как «виртуальный», но все же пытаются переписать его в подклассе. Хотя это, очевидно, будет принято, поведение будет не совсем таким, как предполагалось: метод не является виртуальным, поэтому доступ через указатели к суперклассу закончится вызовом старого (суперкласс ') метода вместо нового (подкласс') метода.
Добавление «переопределить» однозначно устраняет это: с помощью этого мы сообщаем компилятору, что ожидаются три вещи:
Если какой-либо из них является ложным, то сообщается об ошибке.
* примечание: выходной параметр иногда имеет другой, но связанный тип. Читайте о ковариантных и контравариантных преобразованиях, если интересно.
Найденное « переопределение » полезно, когда кто-то обновил сигнатуру виртуального метода базового класса, например, добавил необязательный параметр, но забыл обновить сигнатуру метода производного класса. В этом случае методы между базовым и производным классом больше не являются полиморфными отношениями. Без объявления переопределения трудно обнаружить такую ошибку.
override
это отличный способ для выявления таких проблем, хорошее тестирование юнит-тестов также должно помочь.
Да это так. Это проверка, чтобы убедиться, что никто не пытается переопределить и испортить его через испорченную подпись. Вот страница Wiki, которая объясняет это подробно и имеет короткий иллюстративный пример:
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
Проект стандарта C ++ 17
После просмотра всех override
обращений к черновику стандарта C ++ 17 N4659 единственная ссылка, которую я могу найти на override
идентификатор:
5 Если виртуальная функция помечена с помощью переопределения virt-спецификатора и не переопределяет функцию-член базового класса, программа имеет неверный формат. [ Пример:
struct B { virtual void f(int); }; struct D : B { virtual void f(long) override; // error: wrong signature overriding B::f virtual void f(int) override; // OK }
- конец примера]
поэтому я думаю, что, возможно, взорвать неправильные программы на самом деле единственный эффект.