The following rule states:
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c128-virtual-functions-should-specify-exactly-one-of-virtual-override-or-final
Use either virtual, override or final.
However, it doesn't indicate a preference to use in the following case:
class I { void f() = 0; };
class A final : public I { virtual void f() override final {} };
Does this rule imply we should make A::f() override or final? (With A being a final class)
Since final can only be applied to virtual functions, if you follow the rule by not marking a function virtual on the same line where you mark it final, then final will cause a compile-time error if there is no matching virtual function declared in the base class. [1] This behavior makes override redundant.
The rule states, that override means non-final overrider, while final means final overrider. In your example, A::f() is a final overrider, therefore you should use final and not override or virtual.
So if I understand you correctly you prefer class I { void f() = 0; }; class A final : public I { void f() final {} }; over class I { void f() = 0; }; class A final : public I { void f() override {} };? This feels uncomfortable to me, whats the point of the final identifier on the class level in that case?
Yes. That's how I understand the guideline and I prefer to follow it.
The final on the class prevents subclassing, while the final on the virtual functions prevent further overriding. While final on the class implies that, it also says more. In these classes, final on virtual functions is equivalent to override, but is harmless, makes local reasoning (e.g. in diffs) easier and makes it possible to follow this useful guideline without thinking, i.e. freeing up mental resources for important things.
Editors call: We'll add a cross-reference to C.139 and note that it doesn't matter whether a function is declared with override or final if the whole class is already final.
Most helpful comment
Since
finalcan only be applied to virtual functions, if you follow the rule by not marking a functionvirtualon the same line where you mark itfinal, thenfinalwill cause a compile-time error if there is no matching virtual function declared in the base class. [1] This behavior makesoverrideredundant.The rule states, that
overridemeans non-final overrider, whilefinalmeans final overrider. In your example,A::f()is a final overrider, therefore you should usefinaland notoverrideorvirtual.[1] https://godbolt.org/z/dKLFqr