In various explanations of C++11's final
keyword, I'm seeing examples like this.
class base
{
public:
virtual void f() final;
};
class derived : public base
{
public:
virtual void f(); // Illegal due to base::f() declared final.
};
Is this actually a useful use of final
? Why would you declare a virtual function in a base class (implying that it will be usefully overrideable in derived classes) and then immediately mark it as final
(negating that implication)? What is the utility of virtual void f() final
?
I can see the value of marking derived::f()
final rather than base::f()
. In this case, base::f()
presumably had a good design-based reason for why f()
should be virtual, and derived::f()
separately has a good design-based reason for why no further-derived class should override its implementation.
If you don't want the function overridden polymorphically, why not just leave off the virtual keyword? Of course, derived classes might still override the function non-polymorphically. Is the purpose of virtual void f() final
in the base class therefore to make base::f()
firmly non-overrideable in any way—either as a virtual or non-virtual function? If so, then it seems a bit unfortunate that we must add the virtual
keyword in this case only to enable use of final
. I would think that it should then be legal to mark even non-virtual functions as final.
Why use virtual void f() final
for a function originating in a base class when the sense of virtual
and the sense of final
seem to contradict?
Yes, at least temporarily.
I found myself in a relatively large and unfamiliar existing C++ source code base. Much of the code was written prior to C++11. I found that I wanted to ensure that all overrides of a virtual function in a base class were marked with
override
. The hard part is locating all of those overrides.I marked the virtual function in the base class with
final
, and the compiler quickly showed me where every single override was declared. It was then very easy to decorate the overrides how I wanted, and remove thefinal
from the virtual in the base class.You can mark it
virtual
to indicate that it is 'virtual' in the class you are inheriting from (even though you don't have to do this), and mark itfinal
to indicate that no class deriving from your class may override it further. This may happen when you are implementing an abstract base class, for example. This is C++11, so it's not useful;override
is a much better indication, since it is enforced by the compiler.Another possibility: you want this method not to be overridden, but you want to be able to change that without recompilation. Remember that
virtual
means it is in the virtual table. even if the compiler will not let you override it.I think the purpose of the example you have shown is to demonstrate priorities between
virtual
and final, and nothing more. It is a minimal use offinal
, not a useful one.Marking a non-virtual method as
final
makes no sense, since you cannot override them anyway. If you want the compiler to prevent hiding, that is a completely different issue, that has nothing to do with the method beingfinal
. In a sense, non-virtual methods are final already, but hidable.The alternative is a non-virtual function. But non-virtual function can be hidden by a derived class. So if you want to prevent a function hiding, it can be specified as virtual final one.