AUTOSAR C++14 Rule A12-8-4

Переместитесь конструктор не должен инициализировать его члены класса и базовые классы с помощью семантики копии

Описание

Управляйте определением

Переместитесь конструктор не должен инициализировать его члены класса и базовые классы с помощью семантики копии.

Объяснение

На C++ операции пересылки передают владение ресурсов вместо того, чтобы копировать сами ресурсы от исходного объекта до целевого объекта. Поскольку конструкторы перемещения не копируют ресурсы, эти конструкторы быстрее, чем конструкторы копии. Рассмотрите этот код где объект CopyTarget создается из копии и объект MoveTarget создается из перемещения из объекта Source.

class BigData{
	//...
	BigData(BigData&&){  //Move Constructor
		//...
	} copy constructed
	BigData(const BigData&){  //Copy Constructor
		//...
	}
private:
	std::map<int, std::string> BigBook;
};

int main(){
	BigData Source;
	BigData CopyTarget = Source;
	BigData Movetarget = std::move(Source);
	//...
}

Когда создающий копию CopyTarget, компилятор копирует ресурс Source::BigBook от Source к CopyTarget. После конструкции копии оба из этих объектов имеют копию ресурса BigBook. Когда создающий перемещение Movetarget, компилятор передает владение ресурса Source::BigBook к MoveTarget. Поскольку конструкция перемещения не копирует ресурс физически, это быстрее, чем конструкция копии.

Конструкция перемещения является стратегией оптимизации. Вы ожидаете, что конструкция перемещения является более дешевой и быстрее, чем конструкция копии. Инициализирующие копию элементы данных и базовые классы могут сделать конструктора перемещения медленным и неэффективным, который уменьшает эффективность программы. Разработчики ожидают, что конструкция перемещения использует семантику перемещения только. Неожиданно использующая семантика копии в конструкторах перемещения может ввести утечки ресурсов и несоответствие в будущей разработке. При авторской разработке конструкторов перемещения инициализируйте элементы данных и базовые классы при помощи семантики перемещения. Можно скопировать - инициализируют скалярные элементы данных, не нарушая это правило.

Вы можете использовать std::move() реализовывать семантику перемещения в вашем коде. Когда вы используете std::move() чтобы переместить объекты, объявите объекты или элементы данных без спецификатора const. Для получения дополнительной информации смотрите AUTOSAR C++14 Rule A18-9-3.

Реализация Polyspace

Когда конструктор перемещения не использует семантику перемещения, чтобы инициализировать нескалярные элементы данных и базовые классы, Polyspace® отмечает свое объявление. Например, если конструктор перемещения инициализирует базовый класс при помощи конструктора по умолчанию вместо конструктора перемещения, Polyspace отмечает объявление конструктора перемещения.

Поиск и устранение проблем

Если вы ожидаете нарушение правила, но не видите его, обратитесь к Кодированию Стандартных Нарушений, Не Отображенных.

Примеры

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

В этом примере показано, как флаги Polyspace перемещают конструкторов, который использует инициализацию копии и конструкцию по умолчанию.

#include<cstdint>
#include<string>
#include<map>
#include <vector>
class BigData{
public:
	BigData()=default;
	//...
	BigData(BigData&& oth): //Compliant
	BigBook(std::move(oth.BigBook)),  
	Length(oth.Length)	
	{  
		//...
	} 
	
private:
	std::map<int, std::string> BigBook;
	int Length;
};

class slowBigData{
	//...
	slowBigData(slowBigData&& oth): //Noncompliant
	BigBook(oth.BigBook),  
	Length(oth.Length)	           
	{  
		//...
	} 
	
private:
	std::map<int, std::string> BigBook;
	int Length;
};

class BigData2: public BigData{
	//...
	BigData2(BigData2&& oth):BigData() //Noncompliant
	
	{  
		BigVector = std::move(oth.BigVector);
		//...
	} 
	
private:
	std::map<int, std::string> BigBook;
	std::vector<int> BigVector;
	int Length;
};

class BigData3: public BigData{
	//...
	BigData3(BigData3&& oth):BigData(std::move(oth)) //Compliant
	
	{  
		str = std::move(oth.str);
		//...
	} 
	
private:
	std::map<int, std::string> BigBook;
	int Length;
	std::string str;
};

  • Конструктор перемещения класса BigData инициализирует элемент данных BigBook при помощи семантики перемещения. Конструктор перемещения инициализирует скалярный член Length при помощи семантики копии. Этот конструктор перемещения совместим, потому что копирование скалярных элементов данных не нарушает это правило.

  • Конструктор перемещения класса slowBigdata инициализирует элементы данных при помощи семантики копии. Этот конструктор перемещения нарушает правило, и Polyspace отмечает объявление конструктора перемещения.

  • Конструктор перемещения класса BigData2 вызывает конструктора по умолчанию базового класса, который может сделать код медленным и неэффективным. Polyspace отмечает объявление этого конструктора перемещения. Конструктор перемещения класса BigData3 вызывает конструктора перемещения базового класса. Этот конструктор перемещения совместим с этим правилом.

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

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