Ответ 1
Если вы не отмечаете функцию как virtual
и final
, тогда дочерний класс может реализовать эту функцию и скрыть функцию базового класса.
Выполняя функцию virtual
и final
, дочерний класс не может переопределить или скрыть функцию.
Я читаю удивительный удивительный учебник по С++ 11, и автор предоставляет этот пример, объясняя ключевое слово final
:
struct B {
virtual void f() const final; // do not override
virtual void g();
};
struct D : B {
void f() const; // error: D::f attempts to override final B::f
void g(); // OK
};
Так что имеет смысл использовать здесь ключевое слово final
? На мой взгляд, вы можете просто не использовать здесь ключевое слово virtual и предотвращать переопределение f()
.
Если вы не отмечаете функцию как virtual
и final
, тогда дочерний класс может реализовать эту функцию и скрыть функцию базового класса.
Выполняя функцию virtual
и final
, дочерний класс не может переопределить или скрыть функцию.
Да! В приведенном примере ключевое слово final
предотвращает переопределение f()
всех производных классов, как вы правильно говорите. Если функция не является виртуальной, D:f()
разрешено скрывать версию функции базового класса:
struct B {
void f() const; // do not override
virtual void g();
};
struct D : B {
void f() const; // OK!
void g(); // OK
};
Используя f()
a virtual
и final
, любая попытка переопределения или скрытия вызывает ошибку компиляции.
Ваша интуиция правильная: создание функции virtual
только для немедленного закрытия ее с помощью final
не имеет преимущества над не виртуальной функцией. Это всего лишь короткий фрагмент фрагмента, чтобы продемонстрировать эту функцию.
Кроме того, как описано в других ответах, это фактически нарушает функцию сокрытия - вы никогда не сможете иметь функцию f
с тем же списком параметров в D
или любом из его производных классов.
Это компромисс, который нужно сделать, когда вы решите ограничить f
в своей модели. Поскольку здесь нет возможности выполнить виртуальный вызов, у вас есть недостаток и отсутствие выгоды.