2012-12-14 5 views
153

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

Разве что?

+42

Да.⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣ –

+11

Это не двойная проверка. Это единственная проверка. –

+0

@ Никос хорошая точка;), исправлено – aiao

ответ

183

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

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

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

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

+51

+1: Хотя, к сожалению, это немного красная селедка, когда люди предполагают, что новая функция 'override'« исправляет »это; вы должны помнить, как использовать его, так же, как вы должны были вспомнить, чтобы написать 'const';) –

+0

Я только что понял, что определения явного класса не попали в C++ 11. Да. – aschepler

+1

@aschepler И что бы определяло определение класса «явное»? Никогда об этом не слышал. –

3

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

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

23

Википедия цитата:

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

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

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

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

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

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

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

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

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

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

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

18

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

+0

+1. Хотя, несмотря на то, что 'override' - отличный способ обнаружить такие проблемы, также следует помочь в хорошем тестировании модулей. –

+0

Именно поэтому я так взволнован этим новым спецификатором. Единственная проблема заключается в том, что эта функция должна быть уже применена для предотвращения ошибок, вызванных изменениями в базовых классах. ;-) – Wolf

 Смежные вопросы

  • Нет связанных вопросов^_^