При добавлении спецификатора final
мы запрещаем переопределять метод в базовом классе. Тогда зачем нам нужен в базовом классе создавать виртуальный метод, если можно его оставить обычным? Для чего еще используется виртуальный модификатор?
class Base
{
public:
virtual void doSomething(int x) final;
};
Например вот так:
class Base
{
public:
void doSomething(int x);
};
Такая комбинация virtual
и final
будет формально корректной, но фактически бессмысленной. Так что вопрос тут скорее к автору кода: зачем они объявили такой метод?
Если задаться целью попритягивать за уши оправдания для такого использования, то возможной причиной может быть желание формально сделать класс полиморфным. (Например, захотелось мне для каких-то моих целей, чтобы dynamic_cast<void *>
работал с указателями типа Base *
, а класс Base *
как назло у меня не является полиморфным.) Для этого надо создать в нем хотя бы один виртуальный метод, даже если виртуальность этого метода на самом деле "никому больше не нужна". Традиционно в таких ситуациях виртуальным делают деструктор. Но в качестве странноватого альтернативного варианта можно рассмотреть и такую "фиктивную" виртуальность, как в вашем примере.
P.S. Не надо называть невиртуальные методы "статическими". Термин статический метод в языке С++ уже зарезервирован и используется для совсем других целей.
Стандартом c++11
спецификатор final
определяется как virt-specifier
, поэтому он не имеет смысла для невиртуальных методов и генерирует ошибку:
marked final, but is not virtual
Однако, как правило, final
не используется в определении виртуальных методов базового класса.
final
используется в классах-наследниках, которые переопределяют метод, чтобы предотвратить дальнейшее изменение реализации метода.
Поэтому final
зачастую используется вместе со спецификатором override
.
Спецификатор final
обычно не используют в базовом классе (смотри ответ vp_arth).
Данный модификатор используется, чтобы запретить переопределение виртуальной функции в классе-наследнике, поэтому обычно используется при наследовании более чем на 2 уровня.
struct A {
virtual void foo() { std::cout << "I'm A!\n"; }
};
struct B : A {
virtual void foo() override final { std::cout << "I'm B!\n"; }
};
struct C : B {
virtual void foo() override { std::cout << "I'm C!\n"; } // <- запрещено, ошибка времени компиляции
};
P.S. В наследниках ключевое слово virtual
не несёт смысловой нагрузки, но для наглядности оставил.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Как мне в Qt5 настроить так чтобы на одном листе A4 печатать два формата A5?
Добавил файл (minifyjs),и выдает такие ошибки