Подтвердить что ты не робот

Использование "виртуального" в производном классе

Недавно я видел код в производном классе, в котором программист помещал virtual перед переопределенными функциями. Это распространено? Я думал, что это было очень странно, и это отвлекало меня от страха.

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

Пример:

class B {
 public:
  virtual void foo();
  ....
};

class D : public B {
 public:
  virtual void foo(); // could have just put void foo();
  ...
};
4b9b3361

Ответ 1

virtual необходим для переопределяемых функций на самом высоком (наименее производном) уровне. Это необязательно, но безвредно на более низких (более производных) уровнях. Это хорошо для самодокументирования кода.

Ответ 2

Это очень распространено. Многие руководства по стилю рекомендуют это, например. Google. Целью является повышение удобочитаемости кода.

Ответ 3

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

Ответ 4

Еще один способ повысить удобочитаемость - использовать что-то вроде этого:

class B {
 public:
  virtual void foo();
  ....
};

class D : public B {
 public:
  /*override*/ void foo();
  ...
};

Ответ 5

Я предполагаю, что вы знаете цель виртуального ключевого слова, но задаетесь вопросом, почему он внезапно появляется в подтипе. Если я ошибаюсь, мой ответ, вероятно, не будет иметь большого смысла, но любая ссылка С++ будет делать.

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

Однако, несмотря на юридическую силу, не считается хорошим дизайном иметь невиртуальный метод в базовом классе и виртуальный в переопределенной версии.

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

Ответ 6

Эти ответы (и эта практика) устарели. Начиная с С++ 11, вы должны использовать override, чтобы явно указать, что виртуальная функция переопределяет другую виртуальную функцию. Ваш компилятор вызовет ошибку, если вы попытаетесь override что-то, что не является виртуальной функцией в базовом классе!

Ответ 7

Это поможет, если и будущие деривации. Если кто-то хочет получить класс D и иметь виртуальные функции, тогда его легко понять