Почему конструктор копирования и оператор присваивания запрещены? - PullRequest
6 голосов
/ 06 августа 2010
#undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName)    \
   TypeName(const TypeName&);                           \
   void operator=(const TypeName&)

Я читаю открытый исходный код от Google.Почему конструктор копирования и оператор присваивания запрещены?

Ответы [ 3 ]

12 голосов
/ 06 августа 2010

Для предотвращения копирования или назначения экземпляров класса. Большинство классов не должны допускать копирования. Рассмотрим, например, класс BankAccount - если вы пишете программное обеспечение для банка, они не будут рады, если вы создадите копии счетов, а затем примените кредиты и дебеты к этим различным копиям.

7 голосов
/ 06 августа 2010

Проблема с конструктором копирования и оператором копирования-назначения заключается в том, что компилятор автоматически генерирует реализации, если они не объявлены явно.

Это может легко вызвать непреднамеренные проблемы.Если класс имеет нетривиальный деструктор, он почти всегда должен предоставлять свои собственные реализации для конструктора копирования и оператора копирования-назначения (это Закон Большой Тройки ), так как компилятор по умолчанию -сгенерированные обычно делают неправильные вещи.

Нарушение закона большой тройки часто приводит к ошибкам, таким как двойное освобождение членов данных и повреждение памяти.Нередко возникают ошибки такого рода, потому что автору класса никогда не приходится задумываться о поведении копирования, а потребителям легко непреднамеренно копировать объекты.

Если автор класса не задумывался окак правильно копировать экземпляры этого класса (или, если у класса нет тривиального деструктора), тогда лучше явно запретить копирование, чтобы избежать потенциальных проблем.Реализация возможности копирования может быть отложена до тех пор, пока в этом не будет реальной необходимости.

1 голос
/ 06 августа 2010

Если ваш тип содержит указатель или ссылочные члены, или нет смысла копировать его (например, он имеет дескриптор ресурса, который должен быть освобожден в деструкторе), то рекомендуется отключить конструктор копирования и присвоениеоператор.В C ++ 0x (например, в g ++ 4.4 или более поздней версии в режиме -std = c ++ 0x) вы можете объявить их удаленными.В старых компиляторах вы просто объявляете их закрытыми и не реализованными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...