Должны ли методы, реализующие чистые виртуальные методы класса интерфейса, быть объявлены виртуальными?

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

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

7 ответов


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

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


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


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


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

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

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

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

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

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

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

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


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

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


Как только "виртуальный", он виртуальный вплоть до последнего ребенка. Afaik, это особенность c++.


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