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