Если класс объявляет операцию копирования или перемещения или деструктор с помощью «= default», «= delete» или с помощью описания, предоставленного пользователем, то также должны быть объявлены все остальные из этих пяти специальных функций-членов.
Если класс объявляет операцию копирования или перемещения или деструктор либо через «= default», «= delete», либо через предоставленное пользователем объявление, то также должны быть объявлены все остальные из этих пяти специальных функций-членов.
Эти специальные функции-члены вызываются для операций копирования или перемещения:
Конструктор копирования
Копировать оператор назначения
Конструктор перемещения
Оператор назначения перемещения
Деструктор
Если явно не объявить ни одну из этих функций, компилятор определяет их неявно. Это неявное определение реализует неглубокое копирование объектов и может вызвать ошибки. Если необходимо явным образом объявить какую-либо из специальных функций-членов, необходимо объявить все из них. Например, предположим, что требуется скопировать объект, содержащий необработанный указатель, в динамически выделенную память. Неявный конструктор копирования неглубоко копирует объект, после чего исходный указатель и скопированный указатель указывают на одну и ту же память. Если один из объектов уничтожен, выделенная память освобождается, оставляя висящий указатель в другом объекте. Доступ к висящему указателю может привести к ошибкам сегментации. Поскольку все специальные функции-члены тесно связаны, неявная реализация других функций может привести к подобным ошибкам. Для управления жизненным циклом динамически выделенного ресурса явным образом объявите все пять специальных функций-членов (правило пяти). Кроме того, можно использовать объекты, в которых управление памятью правильно реализовано в неявном определении специальных функций-членов, и явно объявить ни одну из них (правило нуля).
При явном объявлении некоторых, но не всех специальных функций-членов компилятор может предотвратить использование необъявленных специальных функций-членов. Например, если явным образом объявляется только конструктор копирования или функции деструктора класса, компилятор больше не определяет конструктор перемещения и оператор назначения перемещения неявно. Класс становится классом только для копирования, возможно, непреднамеренно. И наоборот, если явным образом объявляется только конструктор перемещения и оператор назначения перемещения, компилятор отключает конструктор копирования и оператор назначения копирования, определяя их как удаленные. Класс становится классом, предназначенным только для перемещения, что, возможно, не было вашим намерением. Чтобы избежать таких нежелательных эффектов, либо следуйте Правилу Пяти, либо Правилу Нуля.
Конструктор класса не является частью этого правила.
Polyspace ® помечает классы, которые явно объявляют некоторые, но не все из пяти специальных функций-членов. Обратите внимание, что конструктор перемещения и операторы назначения перемещения были введены в C++ 11. Polyspace не делает никаких исключений для старых кодов.
Если вы ожидаете нарушения правила, но не видите его, обратитесь к разделу Нарушения стандартов кодирования не отображаются.
| Группа: Специальные функции-члены |
| Категория: Обязательно, Автоматизировано |