AUTOSAR C++14 Rule A12-1-5

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

Описание

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

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

Объяснение

Классы C++ часто имеют несколько конструкторов с различными синтаксисами. У этих инициализаторов могут иметь некоторые общие инициализации. Например, в этом коде, обоих конструкторах класса Circle инициализируйте непостоянные члены xY и r.

class Circle{
	int x;
	int y;
	int r;
	public:
	Circle(int x_in, int y_in, int r_in): x{x_in}, y{y_in},r{r_in}{
		//...
	}
	Circle( int x_in, int y_in): x{x_in}, y{y_in}, r{0}{
		//...
	}
	//...
};
Ожидается, что у всех конструкторов класса есть эквивалентное поведение. Когда эти общие задачи неоднократно выполняются в нескольких конструкторах, любые непреднамеренные различия могут привести к беспорядку и неожиданным результатам. Выполнение общих задач неоднократно может также быть утомительным.

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

Реализация Polyspace

Polyspace® отмечает класс, объединение или структуру, если какой-либо из их непостоянных членов инициализируется в нескольких конструкторах. Polyspace не отмечает:

  • Скопируйте или переместите конструкторов, которые не используют конструкторов делегата.

  • Массивы, которые инициализируются в нескольких конструкторах.

  • Объекты, которые являются инициализированным полем полем в нескольких конструкторах.

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

Если вы ожидаете нарушение правила, но не видите его, относитесь, чтобы Диагностировать, Почему Кодирующие Стандартные Нарушения Не Появляются как ожидалось.

Примеры

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

#include <cstdint>
#include <string>
#include<initializer_list>

class Circle // Noncompliant
{
public:
	Circle(std::int32_t xx, std::int32_t yy, std::int32_t rr):x{xx}, y{yy}, r{rr}
	{}

	Circle(std::int32_t xx, std::int32_t yy):Circle(xx,yy,0) //Delegated constructor
	{}

	Circle(std::int32_t xx):x(xx),y(1),r(1) // Could be delegated
	{}

	Circle():x(0),y(0),r(0)//Could be delegated
	{}

protected:
	std::int32_t x;
	std::int32_t y;
	std::int32_t r;
};
class Flag // Compliant
{
public:
	Flag(bool a):a(a)
	{}

	Flag():a(0)
	{}

protected:
	const bool a;
};

class Tuple    // Noncompliant
{
public:
	Tuple(std::initializer_list<float> ilist) {
		auto* p = ilist.begin(); 
		x = *p++; 
		y = *p++;
		z = *p++;
	}
	Tuple(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}

	float x = 0, y = 0, z = 0;
};

Этот пример показывает совместимые и несовместимые классы.

  • Класс Circle имеет четырех конструкторов. Это делегирует общие инициализации во втором конструкторе, но повторяет инициализации в третьих и четвертых конструкторах. Это повторение может привести к неожиданным результатам. Polyspace отмечает класс.

  • Класс Flag повторяет инициализацию его члена a в двух конструкторах. Поскольку a const, Polyspace не отмечает класс.

  • Класс Tuple инициализирует его nonconst члены неоднократно в двух конструкторах. Polyspace отмечает класс.

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

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