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