Должны ли методы, которые реализуют чисто виртуальные методы класса интерфейса, также быть объявлены виртуальными? - PullRequest
7 голосов
/ 26 октября 2010

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

Есть ли необходимость в объявлении методов в реализации как виртуальных?Если да, то почему?

Ответы [ 7 ]

9 голосов
/ 26 октября 2010

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

Но хорошие практики кодирования говорят объявить эти методы виртуальными.

7 голосов
/ 26 октября 2010

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

7 голосов
/ 26 октября 2010

Реальная потребность - нет.Как только метод объявлен как виртуальный в базовом классе, он остается виртуальным для всех производных классов.Но хорошо знать, какой метод является виртуальным, а какой - нет, вместо проверки этого в базовом классе.Кроме того, в большинстве случаев вы не можете быть уверены, будет ли ваш код получен или нет (например, если вы разрабатываете какое-то программное обеспечение для какой-то фирмы).Как я уже сказал, это не проблема, так как однажды объявленная как виртуальная, она остается виртуальной, но на всякий случай .. (:

5 голосов
/ 26 октября 2010

Нет необходимости помечать их как виртуальные.

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

class CommsObject {
   virtual OnConnect();
   virtual OnRawBytesIn();
};

class XMLStream : public CommsObject {
    virtual OnConnect();
            OnRawBytesIn();
    virtual OnXMLData();
};

В этом примере OnConnect задокументирован как виртуальный в обоих классах, потому что имеет смысл, что потомок всегда хотел бы знать.OnRawBytesIn не имеет смысла «экспортировать» из XMLStream, поскольку он использует его для обработки необработанных байтов и генерации проанализированных данных - о чем он уведомляет с помощью OnXMLData ().

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

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

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

4 голосов
/ 26 октября 2010

Нет, он не нужен и не предотвращает ошибок кодирования, хотя многие кодеры предпочитают его ставить.

Как только C ++ 0x станет массовым, вы сможете использовать вместо него спецификатор override.

2 голосов
/ 26 октября 2010

Когда-то «виртуальный», он виртуальный вплоть до последнего ребенка.Афайк, это особенность c ++.

1 голос
/ 26 октября 2010

Если вы никогда не наследуете класс, нет смысла делать его методы виртуальными.

...