As I understand it, the override
keyword states that a given declaration implements a base virtual
method, and the compilation should fail if there is no matching base method found.
My understanding of the final
keyword is that it tells the compiler that no class shall override this virtual
function.
So is override final
redundant? It seems to compile fine. What information does override final
convey that final
does not? What is the use case for such a combination?
No
final
does not necessarily implyoverride
. In fact, you could declare avirtual
function that you immediately declarefinal
see here. Thefinal
keyword simply states that no derivedclass
can create an override of this function.The
override
keyword is important in that it enforces that you are indeed actually overriding a virtual function (instead of declaring a new unrelated one). See this post regardingoverride
So long story short, they each serve their own particular purpose, and it is often correct to use both.
final
does not necessarily imply that the function is overridden. It's perfectly valid (if of somewhat dubious value) to declare a virtual function asfinal
on its first declaration in the inheritance hierarchy.One reason I can think of to create a virtual and immediately final function is if you want to prevent a derived class from giving the same name & parameters a different meaning.
final
does not require the function to override anything in the first place. Its effect is defined in [class.virtual]/4 asThat's it. Now
override final
would simply mean„This function overrides a base class one (
override
) and cannot be overriden itself (final
).“final
on it's own would impose a weaker requirement.override
andfinal
have independent behavior.Note that
final
can only be used for virtual functions though - [class.mem]/8Hence the declaration
Is effectively the same as
Since both require
foo
to override something - the second declaration by usingoverride
, and the first one by being valid if and only iffoo
is implicitly virtual, i.e. whenfoo
is overriding a virtual function calledfoo
in a base class, which makesfoo
in the derived one automatically virtual. Thusoverride
would be superfluous in declarations wherefinal
, but notvirtual
, occurs.Still, the latter declaration expresses the intent a lot clearer and should definitely be preferred.
The following code (with the
final
specifier) compiles. But compilation fails whenfinal
is replaced withoverride final
. Thusoverride final
conveys more information (and prevents compilation) than justfinal
.Essentially,
override final
says this method cannot be overridden in any derived class and this method overrides a virtual method in a base class.final
alone doesn't specify the base class overriding part.(Skip to the end to see the conclusion if you're in a hurry.)
Both
override
andfinal
can appear only in declaration in a virtual function. And both key words can be used in the same function declaration, but whether it is useful to use them both depends on situations.Take the following code as an example:
The output is
Compare
f1()
andf6()
. We know thatoverride
andfinal
is indepent sematically.override
means the function is overriding a virtual function in its base class. Seef1()
andf3()
.final
means the function cannot be overrided by its derived class. (But the function itself need not override a base class virtual function.) Seef6()
andf4()
.Compare
f2()
andf3()
. We know that if a member function is declared withoutvirtual
and withfinal
, it means that it already override a virtual function in base class. In this case, the key wordoverride
is redundant.Compare
f4()
andf5()
. We know that if a member function is declared withvirtual
and if it is not the first virtual function in inheritance hierarchy, then we should useoverride
to specify the override relationship. Otherwise, we may accidentally add new virtual function in derived class.Compare
f1()
andf7()
. We know that any member function, not just virtual ones, can be overridden in derived class. Whatvirtual
specifies is polymorphism, which means the decision as to which function to run is delayed until run time instead of compile time. (This should be avoid in practice.)Compare
f7()
andf8()
. We know that we can even override a base class function and make it a new virtual one. (Which means any member functionf8()
of class derived fromD
will be virtual.) (This should be avoid in practice too.)Compare
f7()
andf9()
. We know thatoverride
can help us find the error when we want to override a virtual function in derived class while forgot to add key wordvirtual
in base class.In conclusion, the best practice in my own view is:
virtual
in declaration of the first virtual function in base class;override
to specify override virtual function in derived class, unlessfinal
is also specified.