Использование 'virtual' в производном классе - PullRequest
19 голосов
/ 11 февраля 2010

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

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

EX:

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

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

Ответы [ 7 ]

26 голосов
/ 11 февраля 2010

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

9 голосов
/ 11 февраля 2010

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

5 голосов
/ 14 января 2016

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

4 голосов
/ 11 февраля 2010

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

3 голосов
/ 11 февраля 2010

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

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

class D : public B {
 public:
  /*override*/ void foo();
  ...
};
3 голосов
/ 11 февраля 2010

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

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

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

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

1 голос
/ 11 февраля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...