2016-10-08 3 views
22

В последние недели что-то подталкивает мой мозг к виртуальному и переопределению. Я узнал, что когда вы наследуете виртуальную функцию, вы должны добавить virtual, чтобы компилятор знал, что нужно искать правильную функцию. Впоследствии я узнал также, что в C++ 11 есть новое ключевое слово - переопределить. Теперь я немного смущен; Нужно ли мне использовать как виртуальные, так и переопределяющие ключевые слова в моей программе, или лучше использовать только один из них?виртуальный? переопределить? или оба? C++

объясниться - примеры кода того, что я имею в виду:

class Base 
{ 
public: 
    virtual void print() const = 0; 
    virtual void printthat() const = 0; 
    virtual void printit() const = 0; 
}; 

class inhert : public Base 
{ 
public: 
    // only virtual keyword for overriding. 
    virtual void print() const {} 

    // only override keyword for overriding. 
    void printthat() const override {} 

    // using both virtual and override keywords for overriding. 
    virtual void printit() const override {} 
}; 

Что такое лучший метод?

+2

Вы должны использовать ключевое слово 'override' всякий раз, когда вы намереваетесь переопределить метод. Таким образом, если вы ошибочно назовете имя в производном классе, вы получите сообщение об ошибке, указывающее, что метод не найден для переопределения – Eric

+2

[Является ли ключевое слово 'override' просто проверкой для переопределенного виртуального метода?] (Http: // stackoverflow.com/questions/13880205/is-the-override-keyword-just-a-check-for-a-overriden-virtual-method) – Solarflare

+1

Более интересный вопрос: «Что произойдет, если я использую переопределение без виртуального» – Eric

ответ

42

Когда вы переопределяете функцию, вам технически не нужно писать virtual или override.

Первоначальная декларация базового класса требует ключевого слова virtual, чтобы пометить его как виртуальное.

В производном классе функция является виртуальной с помощью того же типа, что и функция базового класса.

Однако override может помочь избежать ошибок, вызвав ошибку компиляции, когда предполагаемое переопределение технически не переопределено. Например. что тип функции не совсем похож на функцию базового класса. Или что поддержание базового класса изменяет тип функции, например. добавление аргумента по умолчанию.

Точно так же ключевое слово virtual в производном классе может сделать такую ​​ошибку более тонкой, гарантируя, что функция по-прежнему является виртуальной в дополнительных производных классах.

Так общий совет,

  • Использование virtual для функции декларации базового класса.
    Это технически необходимо.

  • Использовать override (только) для переопределения производного класса.
    Это помогает в обслуживании.

Пример:

struct Base { virtual void foo() {} }; 
struct Derived: Base { void foo() override {} }; 

Примечания:
¹ C++ поддерживает ковариантный сырой указатель и необработанные контрольные результаты. С ковариацией тип переопределения не совсем то же самое. Он имеет совместимый тип.

+3

Из cppreference (http://en.cppreference.com/w/cpp/language/virtual): «Если какая-либо функция-член vf объявлена ​​как виртуальная в классе Base, а некоторый класс Derived, который является производным, непосредственно или косвенно, от базы, имеет декларацию для функции члена с тем же имени параметра списка типа (но не тип возвращаемого значения) CV-Отборочные реф-классификаторами Тогда эта функция в классе Derived также виртуальная (независимо от того, используется ли ключевое слово virtual в его объявлении) и переопределяет Base :: vf (независимо от того, используется ли слово переопределение в его объявлении). " – solstice333

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