В нескольких местах я видел совет, как определить собственный оператор присваивания / конструктор копирования или заблокировать стандартные по умолчанию, объявив их закрытыми.
Тем не менее, единственная опасность, которую я смог найти, была проблема создания копий указателей, которые могли бы быть повисшими указателями позже.
В современном C ++ указатели встречаются редко, и большинство классов просто используют умные указатели (например, из boost или из библиотеки std в C ++ 11). Все еще необходимо объявить оператор присваивания и конструктор копирования для классов, которые не имеют необработанных указателей?
И главным образом: каковы опасности не делать этого? Какое неожиданное поведение может произойти?
Не надо скрывать этих операторов. std::unique_ptr
уже нельзя скопировать (вы можете только переместить его). И другие виды — std::shared_ptr
увеличит внутренний счетчик ссылок, std::weak_ptr
ничего не будет делать, так как имеет lock
метод. Вы можете прочитать больше здесь (Boost libs)
Опасность, связанная с отсутствием определения собственного оператора присваивания / конструктора копирования / перемещения, заключается в возможности неожиданного поведения. Эти операции очень легко вызываются без вашего ведома, вызывая неожиданное поведение. Объявление их как приватных приведет к ошибке компиляции в таких случаях.
Также обратите внимание, что не везде используются умные указатели. Существуют более ограниченные среды (такие как ядро, встроенные и т. Д.), Которые обычно не имеют STL или boost.
Это объясняется в вопросе Что такое правило трех?
Также есть очень хорошее объяснение на следующем сайте:
Могу ли я доверять сгенерированному компилятором конструктору копирования и оператору присваивания?
Сгенерированный компилятором код — ваш лучший друг, при условии, что
Вы придерживаетесь хороших стилей ОО практики и знаете правила. Как объяснил
в части I конструктор копирования, созданный компилятором, и присвоение
Оператор выполняет пошаговое копирование объявленных пользователем членов данных. От
замена типов данных низкого уровня — необработанные указатели и массивы символов для
экземпляр — со своими коллегами из стандартной библиотеки высокого уровня
std :: tr1 :: shared_ptr и std :: string не только исключают
обременительные ошибки, связанные с ручным управлением ресурсами, вы также
гарантируя, что сгенерированный компилятором конструктор копирования и
Оператор присваивания сделает все правильно.