2016-10-25 3 views
4

В Cplusplus в производном классе, если мы определяем функцию-член, чтобы переопределить функцию-член в своем родительском классе, нужно ли объявить виртуальный объект в производном классе?Нужно ли переопределять функции виртуальным?

Например, нам нужно объявить g виртуальным в B, чтобы его переопределить A::g? что одно из следующего верно для вышеуказанной цели?

class A{ 
public: 
void f(){printf("A");} 
virtual void g(){printf("A");} 
} 
class B : public A{ 
public: 
void f(){printf("B");} 
void g(){printf("B");} 
} 

или

class A{ 
public: 
void f(){printf("A");} 
virtual void g(){printf("A");} 
} 
class B : public A{ 
public: 
void f(){printf("B");} 
virtual void g(){printf("B");} 
} 

Спасибо.

ответ

6

Нет, вы этого не сделаете. Функция является виртуальной из первой точки иерархии, где вы объявляете ее как таковую.

Вы можете и должны указать его как override в C++ 11 и далее. Он явно указывает компилятору, что вы пытаетесь переопределить виртуальную функцию в базовом классе. Это, чем испускает ошибку, если вы пропустите имя функции, заблудитесь в параметрах или сделайте что-нибудь еще, что можно считать добавлением перегрузки функции. До C++ 11 предыдущие ошибки молчали бы скомпилировать.

+0

спасибо. почему «вы можете и должны указывать его как переопределение в C++ 11 и далее». – Tim

+0

@ Тим, я сложил свой комментарий в самом ответе. Спасибо за просьбу :) – StoryTeller

2

Они оба делают то же самое. Вам не нужно явно указывать virtual в производном классе, если он является виртуальным в базовом классе.

9

Как только метод является виртуальным в классе, его дочерний класс также имеет этот виртуальный класс, даже если вы не добавляете к ним virtual.

Добавление override является хорошей привычкой, чтобы избежать тонкой ошибки:

class A{ 
public: 
    void f()   { printf("A"); } 
    virtual void g() { printf("A"); } 
}; 
class B : public A{ 
public: 
    void f()   { printf("B"); } 
    void g() override { printf("B"); } 
}; 
+0

@JerryJeremiah: Изменить подпись g на 'void g (int)' или 'void g() const', например, в' B' не будет переопределять виртуальную 'g'. которые могут быть незамеченными. – Jarod42

3

Определения функций-членов virtual в производных классов не являются обязательными. Вы можете сделать переопределение явным, используя C++ 11's override.

2

In Cplusplus, in a derived class, if we define a member function to override a member function in its parent class, do we need to declare the one in the derived class to be virtual?

Из рабочего проекта, [class.virtual]/2 (курсив мой):

If a virtual member function  vf  is declared in a class Base  and in a class  Derived , derived directly or indirectly from  Base , a member function  vf with the same name, parameter-type-list, cv-qualification, and ref-qualifier (or absence of same) as  Base::vf is declared, then  Derived::vf is also virtual (whether or not it is so declared) and it overrides  Base::vf .

Таким образом, нет. Это не требуется.

В эпоху предшествующего C++ 11, объявляя virtual, функции-члены в производных классах помогли читателям понять, что происходит под капотом.
Поскольку C++ 11, override является предпочтительным способом, поскольку он не только помогает читателям, но и заставляет проверять время компиляции, чтобы опечатки в объявлениях не вводили тонкие ошибки.

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