Is there any sense in marking a base class function as both virtual and final? [duplicate]
Asked Answered
F

3

9

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?

Felicle answered 24/5, 2013 at 16:1 Comment(2)
Examples are examples; they're intended to show what the feature does, not necessarily how exactly to use it. This way uses only two classes to show what final means. To use a real-world example would require three: one to initiate the virtual, one to derive from it and be final, and a third to attempt to derive from it and overload it. This way is shorter.Titanite
@NicolBolas I understand the purpose of examples. But does this particular type of example also demonstrate a useful paradigm for use? That's the question.Felicle
F
25

Is there any sense in marking a base class function as both virtual and final?

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 the final from the virtual in the base class.

Faiyum answered 22/10, 2014 at 18:0 Comment(0)
I
4

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 it final 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 of final, 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 being final. In a sense, non-virtual methods are final already, but hidable.

Impostor answered 24/5, 2013 at 16:6 Comment(5)
Marking a function as virtual does not indicate that it is virtual in a base. It indicates that it is virtual in the class being defined, regardless of what a base class may or may not have done.Exhilarate
@Pete Becker: I think he meant in terms of making the code self-documenting. It's common practice to respecify the virtual keyword when overriding a base (especially before C++11 added the override specifier) just so the programmer reading the detived clasd definition knows that a particular method is virtual.Uncommitted
@SeanMiddleditch - that's clearly not what he said.Exhilarate
That's not "clear" at all, but hey, English. It's weird.Uncommitted
@PeteBecker, maybe that's not what you understood, but that's exactly what I meant. I thought 'indicate' is clear enough; turns out it isn't, so if you have a better way to phrase it, you are welcome to edit the answer accordingly.Impostor
J
2

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.

Jonas answered 22/10, 2014 at 11:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.