0
votes

I have a question about using the keyword final in C++. I understand that virtual function is a member function that is declared in the base class, and it is expected to be overridden in the derived classes. By dynamic binding, an appropriate method will be called, depending on the type of the object responsible for the call. However, to prevent a member function in a base class from being overridden in any derived class, we will use the final keyword.

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

Why we use "final" to PREVENT a member function in the base class from being overridden in derived class meanwhile we still have to use the keyword VIRTUAL (ALLOW to override) together.

I tried to delete the word virtual, but I got a compile error: "nonvirtual function cannot be declared with 'final' modifier"

1
If it is not virtual, it can't be overridden.user2100815
I understand, but when we use VIRTUAL (it means we expect it to be overridden), so why do we still have to declare FINAL together (it means we don't want it to be overridden).SlimJamesPham
It means we have met the end of a chain of virtual functions. Beyond this, implementing further virtual functions would not make sense.user2100815

1 Answers

1
votes

First at all, we only can stop overriding functions if they can be overridden at all. So final only makes sense on virtual functions at all.

Still, final applied on a single class's virtual function might appear pretty meaningless. But if you consider a more complex hierarchy, matter changes:

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!
};

Additionally, consider the following:

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!!!
};

Declaring Base::f both virtual and final would prevent hiding as well (but not overloading).

Actually, again this scenario rather makes sense if Base itself already inherited from another polymorphic class. If not and Base is not intended to be inherited, I'd not introduce any virtual functions at all (virtual function calls are more costly than normal function calls!). If then a user still inherits and hides a function – well, his own responsibility...