This rule is part of MISRA C++:2023.
Usage of this content is governed by Sonar’s terms and conditions. Redistribution is
prohibited.
Rule 13.3.1 - User-declared member functions shall use the virtual, override and final specifiers
appropriately
Category: Required
Analysis: Decidable,Single Translation Unit
Amplification
The specifiers are used appropriately when a member function declaration:
- Does not override a function in a base class, and has either no specifier or has the
virtual specifier; or
- Overrides a function in a base class, does not use the
virtual specifier, and does use either the override or
final specifier.
Note: this rule also applies to destructors.
Rationale
When a function is declared that does not override a function in a base class (including the case where the owning class has no base classes), then
it is either not intended to be virtual or it is a virtual function that is expected to be overridden in a derived class. The function declaration
should therefore include either no specifier or the virtual specifier, as appropriate. The use of the override specifier in
this case would render the program ill-formed, whilst use of the final specifier would mean that it is a virtual function that
cannot be subsequently overridden (in which case making it virtual is redundant).
When a function is declared that overrides a virtual function in a base class:
- The
override specifier explicitly documents that this declaration overrides a function in a base class;
- The
final specifier documents that no further overrides are permitted.
Whilst they are permitted by the C++ Standard, the following redundant combinations of specifier shall be avoided:
- Use of
virtual with either override or final;
- Use of
final with override.
The use of a single specifier makes the meaning clearer:
-
virtual — this is a new virtual function this is expected to be overridden;
-
override — this is an override that may or may not be overridden;
-
final — this is an override that cannot be overridden.
Notes:
- Declaring a class itself as
final does not make its virtual member functions override or final; the
compiler is not required to check that the declarations are overrides.
- M23_342: MISRA C++ 2023 Rule 6.4.2 restricts the use of function declarations that hide non-virtual functions in base classes.
Example
class A
{
public:
virtual ~A() = default;
virtual void f1() noexcept = 0; // Compliant
virtual void f2() noexcept {} // Compliant
virtual void f3() noexcept {} // Compliant
void f4() noexcept {} // Compliant
// The following declarations are non-compliant
virtual void f5() noexcept final = 0; // 'virtual' and 'final'
virtual void f6() noexcept final {} // 'virtual' and 'final'
void f7() noexcept final {} // Ill-formed - not virtual
};
class B : public A
{
public:
// The following declarations are non-compliant
~B(); // No specifier given for override
virtual void f1() noexcept override {} // 'virtual' and 'override'
void f2() noexcept override final {} // 'override' and 'final'
void f3() noexcept {} // No specifier given for override
void f4() noexcept override {} // Ill-formed - A::f4() not virtual
};
Copyright The MISRA Consortium Limited © 2023