Main Content

AUTOSAR C++14 Rule A10-3-2

Each overriding virtual function shall be declared with the override or final specifier

Since R2020a

Description

Rule Definition

Each overriding virtual function shall be declared with the override or final specifier.

Rationale

Virtual functions implement polymorphic behavior in a class hierarchy. Once you declare a function as virtual in a base class, all instances of the function with an identical parameter list in the derived classes override the base function implicitly. If you rely on this implicit action by the compiler for implementing polymorphic functions, it can lead to errors. For instance:

  • A function can become inadvertently virtual because its signature matches a virtual function in the base class.

  • A function can become inadvertently non-virtual because there are differences in the parameter list.

Implicitly declaring overriding virtual functions can also make the code hard to read.

To avoid inadvertent errors and to enhance readability, use the specifiers override and final explicitly in every declaration of overriding functions.

Polyspace Implementation

Polyspace® flags the declarations of virtual functions if all of these statements are true:

  • The function is in a derived class.

  • The signature of the function matches the signature of a virtual function in the base class.

  • The declaration of the function lacks the specifier override or final.

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#include <cstdint>
class Base
{
public:
	virtual ~Base() {}
	virtual void F() noexcept = 0;
	virtual void G() noexcept {}
	virtual void Z() noexcept {}
	virtual Base& operator+=(Base const& oth) = 0;
};
class Derived1 : public Base
{
public:
	~Derived1() override {}                         //Compliant
	void F() noexcept{}                             //Noncompliant
	virtual void G() noexcept {}                    //Noncompliant
	void Z() noexcept override {}                   // Compliant
	Derived1& operator+=(Base const& oth) override  // Compliant
	{
		return *this;
	}
};
class Derived2 : public Base
{
public:
	~Derived2() {}                                  //  Noncompliant
	void F() noexcept override {}                   //  Compliant
	void G() noexcept override {}                   //  Compliant
	void Z() noexcept override {}                   //  Compliant
	Derived2& operator+=(Base const& oth)           //  Noncompliant
	{                                               
		return *this;                          
	}                                             
};                                                  
class Derived3 : public Base                        
{                                                   
	void F() noexcept override;                     // Compliant 
};

main(){
	
}

  • The declaration of the function Derived::F() is flagged because its signature matches the signature of Base::F() and its declaration does not contain override or final.

  • The declaration of the function Derived::G() is flagged because its signature matches the signature of Base::G() and its declaration does not contain override or final, even though the declaration uses the specifier virtual.

  • The declaration of the function Derived3::F() in class Derived3 is not flagged because the declaration uses the specifier override.

Check Information

Group: Derived classes
Category: Required, Automated

Version History

Introduced in R2020a