Должны ли методы, реализующие чистые виртуальные методы класса интерфейса, быть объявлены виртуальными?
Я читал разные мнения по этому вопросу. Предположим, у меня есть класс интерфейса с кучей чистых виртуальных методов. Я реализую эти методы в классе, который реализует интерфейс, и я не ожидаю получить от реализации.
есть ли необходимость в объявлении методов в реализации как виртуальных, а также? Если да, то почему?
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
описатель вместо этого.