Использование виртуальной функции с ключевым словом Final - PullRequest
0 голосов
/ 31 марта 2019

У меня есть вопрос об использовании ключевого слова final в C ++. Я понимаю, что виртуальная функция является функцией-членом, которая объявлена ​​в базовом классе, и ожидается, что она будет переопределена в производных классах. При динамическом связывании будет вызван соответствующий метод в зависимости от типа объекта, ответственного за вызов. Однако, чтобы предотвратить переопределение функции-члена в базовом классе в любом производном классе, мы будем использовать ключевое слово final.

void startEngine() final;// Compile error!
virtual void startEngine() final; //No error

Почему мы используем «final», чтобы ПРЕДОТВРАТИТЬ функцию-член в базовом классе, чтобы она не была переопределена в производном классе, в то же время мы все равно должны использовать ключевое слово VIRTUAL (ALLOW для переопределения) вместе.

Я пытался удалить слово virtual, но получил ошибку компиляции: «Невиртуальная функция не может быть объявлена ​​с модификатором final»

1 Ответ

0 голосов
/ 31 марта 2019

Во-первых, мы можем остановить переопределение только в том случае, если они могут быть переопределены . Так что final имеет смысл только для виртуальных функций.

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

class Parent
{
public:
    virtual ~Parent() = default;
    virtual void f();
};
class Child : public Parent
{
public:
    void f() final; // f IS virtual already...
};
class GrandChild : public Child
{
    // cannot override f any more – while Child still could!
};

Дополнительно учтите следующее:

class Base
{
public:
    virtual ~Base() = default;
    void f(); // non-virtual! (i. e. cannot be overridden)
};
class Derived : public Base
{
public:
    void f(); // does not override, but HIDEs Base::f!!!
};

Объявление Base::f как виртуальным, так и финальным также предотвратит сокрытие (но не более загрузка ).

На самом деле, снова этот сценарий имеет смысл, если Base сам уже унаследован от другого полиморфного класса. Если нет и Base не предназначен для наследования, я бы вообще не вводил никаких виртуальных функций (вызовы виртуальных функций обходятся дороже, чем обычные вызовы функций!). Если тогда пользователь все еще наследует и скрывает функцию - ну, это его ответственность ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...