Cppcoreguidelines: C128: Unclear about the preference in a final class

Created on 28 Feb 2020  路  4Comments  路  Source: isocpp/CppCoreGuidelines

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)

Most helpful comment

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.

[1] https://godbolt.org/z/dKLFqr

All 4 comments

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.

[1] https://godbolt.org/z/dKLFqr

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.

Was this page helpful?
0 / 5 - 0 ratings