AUTOSAR C++14 Rule A12-7-1

Если поведение пользовательской специальной функции членства будет идентично неявно заданной специальной функции членства, то это должно быть задано "=default" или оставлено неопределенным

Описание

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

Если поведение пользовательской специальной функции членства будет идентично неявно заданной специальной функции членства, то это должно быть задано "=default" или оставлено неопределенным.

Объяснение

Компиляторы неявно задают специальные функции членства, если эти функции объявляются как =default или оставленный неопределенный. Эти неявно заданные функции сопоставимы, безошибочны, и не требуют обслуживания. Если неявно заданные специальные функции членства достаточны, то заменяющий их на пользовательские функции делает код подверженным ошибкам и более твердым обеспечить. Если класс не управляет ресурсами как необработанный указатель или дескриптор файла POSIX, неявное определение специальных функций членства может быть достаточным. Постарайтесь не задавать специальные функции членства, когда неявные определения будут достаточны.

Конструкция по умолчанию const объекты могут вызвать отказ компиляции, если нестатические элементы данных не инициализируются во время определения. Лучшая практика должна инициализировать нестатические элементы данных в определении класса. В качестве альтернативы инициализируйте const экземпляр при помощи пустого списка инициализаторов. Эти методы позволяют конструктору по умолчанию правильно создать const экземпляры класса.

Реализация Polyspace

Polyspace® повышает средство проверки, если пользовательские специальные функции членства вашего класса совпадают с неявно заданными специальными функциями членства.

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

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

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

Примеры

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

#include <cstdint>
#include <utility>
class A
{
public:
	A() : x(0), y(0) {}                                   // Compliant
	A(std::int32_t first, std::int32_t second)            // Compliant
	: x(first), y(second) {}       
	A(const A& oth) : x(oth.x),y(oth.y){}                 // Noncompliant
	A(A&& oth): x(std::move(oth.x)),y(std::move(oth.y)){} // Noncompliant
	~A(){}                                                // Noncompliant


private:
	std::int32_t x;
	std::int32_t y;
};
class B
{
public:
	B() {}  // Noncompliant 
	B(std::int32_t first, std::int32_t second)// Compliant 
	: x(first), y(second)
	{} 
	B(const B&) = default; // Compliant 
	B(B&&) = default;     // Compliant
	~B() = default;       // Compliant 

private:
	std::int32_t x;
	std::int32_t y;
};
class D
{
public:
	D() : ptr(nullptr) {}  // Compliant - Managing a raw pointer
	D(B* p) : ptr(p) {}    // Compliant - Managing a raw pointer
	D(const D&) = default; // Requires user defined copy constructor
	D(D&&) = default;      // Requires user defined move constructor
	~D() = default;        // Requires user defined destructor

private:
	B* ptr;
};
class E      // Compliant 
{
};

В этом примере, классы AB, и D заданы.

  • Объявление конструктора по умолчанию A совместимо с этим правилом. Правило не применяется к конструкторам не по умолчанию. Поскольку пользовательская копия и конструкторы перемещения A не управляйте никакими ресурсами, и они могут быть заданы как =default или оставленный неопределенный, Polyspace отмечает их.

  • Конструктор по умолчанию B является пользовательским даже при том, что это не управляет никакими ресурсами. Поскольку этот пользовательский конструктор может быть задан как =default или оставленный неопределенный, Polyspace отмечает его. Другие конструкторы B совместимы, потому что они заданы как =default.

  • Класс D содержит необработанный указатель на класс B. Управлять необработанным указателем ptr, конструктор класса D явным образом инициализирует его к nullptr. Поскольку пользовательский конструктор отличается, Polyspace не отмечает его. Поскольку другие специальные функции членства объявляются как =default, эти функции не нарушают это правило. Когда ресурсы управления, такие как необработанный указатель, неявно заданные специальные функции членства являются обычно неправильными. Например, неявный конструктор копии D выполняет мелкую копию ptr, не копируя базовые ресурсы. Когда указатели сырых данных управления, лучшая практика должна задать все специальные функции членства соответственно, чтобы избежать неожиданного поведения.

class B_NC{
	public:
	//B_NC()=default;// Compile fail
	B_NC(){}         //Noncompliant
	int x;
};
class B_C{
	public:
	B_C() = default;//Compliant
	int x = 0;
};
const B_NC a;
const B_C b;

В этом примере, классы B_NC и B_C заданы и const экземпляры этих классов создаются. Согласно стандарту C++, const объект может быть создан неявным конструктором по умолчанию, только если все члены объекта являются "конструируемым значением по умолчанию const". Переменная B_NC::x не может быть создан из const из-значения по умолчанию. Если вы объявляете конструктора как =default, построение const экземпляр B_NC результаты в отказе компиляции. Чтобы разрешить отказ компиляции, вы можете хотеть предоставить пользовательскому конструктору, который идентичен неявному конструктору, таков как конструктор B_NC::B_NC() в предыдущем коде. Хотя этот код компилирует, B_NC::B_NC() несовместимо с этим правилом.

Чтобы разрешить отказ компиляции, не нарушая это правило, инициализируйте нестатические элементы данных класса в его определении, как показано в определении B_C. Поскольку B_C::x может быть создан из const из-значения по умолчанию, const экземпляр B_C может быть создан неявным конструктором по умолчанию. После инициализации нестатических элементов данных, набор конструктор к =default.

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

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