exponenta event banner

Правило AUTOSAR C++ 14 A12-8-7

Операторы назначения должны быть объявлены с помощью ссылочного квалификатора &

Описание

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

Операторы назначения должны быть объявлены с помощью ссылочного квалификатора &.

Объяснение

Можно использовать ссылочные квалификаторы, чтобы указать, применяется ли функция или оператор к lvalues или rvalues. Функции или операторы, применяемые к lvalues, имеют ссылочный квалификатор &. Функции и операторы, применяемые к значениям rvalues, имеют квалификатор ref && в конце своего заявления.

Встроенные операторы назначения в C++ принимают только значения lvalues в качестве входных параметров. Если определяемые пользователем операторы назначения принимают как значение rvalue, так и значение lvalue в качестве входных параметров, это может привести к путанице и ошибкам. Рассмотрим этот код, где определяемый пользователем оператор назначения для класса obj принимает как значения rvalues, так и значения lvalues в качестве входных параметров.

class obj{
	obj& operator=(Obj const&){
		//...
		return *this;
	}
	//...
};

int main(){
	int i,j,k;
	obj a,b,c;

	if((i+j)=k) // compilation error
	//...
	if((a+b)=c) // silent error
	//...
}

  • В первом if оператор «равно» (==) записывается как оператор присвоения (=) из-за опечатки. Поскольку встроенный оператор назначения для int не принимает значения rvalues в качестве входных данных, оператор (i+j) = k вызывает ошибку компиляции.

  • Условие для второго if содержит аналогичную ошибку. Поскольку определяемый пользователем оператор назначения для класса obj принимает как lvalues, так и rvalues в качестве входных данных, оператор (a+b) = c компилирует без ошибок. if блок выполняется неожиданно, в результате чего возникает ошибка молчания.

Чтобы избежать ошибок и путаницы, укажите, что операторы назначения принимают только значения lvalues в качестве входных параметров путем добавления ссылочного квалификатора. & к их декларации.

Внедрение Polyspace

Polyspace ® помечает определяемые пользователем операторы назначения, составного назначения, приращения и уменьшения, если :

  • Они не имеют ссылочного квалификатора & в своей декларации.

  • Они являются функциями-членами класса.

  • Они не объявлены как = delete.

Поскольку ссылочные квалификаторы применимы только к нестатическим функциям-членам, это правило не применяется к операторам назначения, не являющимся членами.

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

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

Примеры

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

В этом примере показано, как Polyspace помечает операторы назначения и операторы приращения или уменьшения, если в их объявлениях не указан квалификатор ссылки &.

#include<cstdint>
class Obj
{
public:
	Obj() = default;
	Obj& operator=(Obj const&) & = default; //Compliant    
	Obj& operator=(Obj&&) & = default;      //Compliant    
	Obj& operator++() & noexcept;           //Compliant    
	Obj& operator--()  noexcept;            //Noncompliant 
	Obj& operator<<=(Obj const&) noexcept;  //Noncompliant   
	Obj& operator>>=(Obj const&) & noexcept;//Compliant   
	Obj& operator+=(Obj const&)&;           //Compliant
	Obj& operator-=(Obj const&);            //Noncompliant
	Obj& operator*=(Obj const&)= delete;    //Compliant
	Obj& operator+(Obj const&)&;            //Compliant  
};

Obj& operator|=(Obj& f,const std::int32_t i) // Rule does not apply 
{
	return f;
}

Obj& Obj::operator+=(Obj const&) &  // Polyspace flags the declaration 
{
	return *this;
}
Obj F1() noexcept
{
	return Obj{};
}
int main()
{
	Obj c;
	//F1() += c; // Compilation Error
	//F1() = c; // Compilation Error
	F1() -= c; // Silent Bug
}

В main(), операторы назначения +=, -=, и = используются с входом rvlaue. Потому что объявления операторов += и = укажите квалификатор ссылки &, использование этих операторов с входным значением rvalue приводит к сбою компиляции. Оператор -= объявляется без квалификатора ссылки &. Использование этого оператора с вводом значения rvalue создает ошибку в режиме молчания.

  • Полиспейс помечает не выделенные операторы назначения элементов, операторы приращения и операторы уменьшения, которые не задают квалификатор ссылки & в своих декларациях.

  • Когда оператор назначения элемента объявлен без квалификатора ссылки & в классе и определяется в другом месте, Polyspace помечает объявление.

  • Polyspace не помечает операторы, не являющиеся членами, без квалификатора ref & поскольку это правило применяется только к нестатическим функциям-членам.

  • Polyspace не помечает удаленные операторы, поскольку использует квалификатор ref & на удаленном операторе не влияет на код.

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

Группа: Специальные функции-члены
Категория: Консультации, Автоматизированные
Представлен в R2020b