exponenta event banner

Правило AUTOSAR C++ 14 A10-3-2

Каждая переопределяющая виртуальная функция должна быть объявлена с переопределением или конечным спецификатором

Описание

Определение правила

Каждая переопределяющая виртуальная функция должна быть объявлена с переопределением или конечным спецификатором.

Объяснение

Виртуальные функции реализуют полиморфное поведение в иерархии классов. После объявления функции как virtual в базовом классе все экземпляры функции с идентичным списком параметров в производных классах неявно переопределяют базовую функцию. Если использовать это неявное действие компилятора для реализации полиморфных функций, это может привести к ошибкам. Например:

  • Функция может стать непреднамеренной virtual потому что его сигнатура соответствует виртуальной функции в базовом классе.

  • Функция может непреднамеренно стать невиртуальной, поскольку в списке параметров имеются различия.

Неявное объявление переопределяющих виртуальных функций также может затруднить чтение кода.

Чтобы избежать случайных ошибок и улучшить удобочитаемость, используйте спецификаторы override и final явно в каждом объявлении переопределяющих функций.

Внедрение Polyspace

Polyspace ® помечает объявления virtual если все эти операторы истинны:

  • Функция находится в производном классе.

  • Сигнатура функции соответствует сигнатуре виртуальной функции в базовом классе.

  • В объявлении функции отсутствует спецификатор override или final.

Поиск неисправностей

Если вы ожидаете нарушения правила, но не видите его, обратитесь к разделу Нарушения стандартов кодирования не отображаются.

Примеры

развернуть все

#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(){
	
}

  • Объявление функции Derived::F() помечен, поскольку его подпись соответствует подписи Base::F() и его объявление не содержит override или final.

  • Объявление функции Derived::G() помечен, поскольку его подпись соответствует подписи Base::G() и его объявление не содержит override или final, даже если в объявлении используется спецификатор virtual.

  • Объявление функции Derived3::F() в классе Derived3 не помечен, поскольку в объявлении используется спецификатор override.

Проверить информацию

Группа: Производные классы
Категория: Обязательно, Автоматизировано
Представлен в R2020a