Когда не поддерживается идиома копирования и свопинга
После прочтения этого об идиоме копирования и свопинга я прочитал this, который гласит: (2):
class_name & class_name :: operator= ( const class_name & ) (2)
(2) Типичное объявление оператора присваивания копии, когда не может использоваться
Когда нам следует избегать использования идиомы копирования и свопинга?
И когда его "нельзя использовать" вообще?
Существуют ли случаи реальной жизни, когда неприменимы как "копирование и смена", так и правило "нуль"?
Я нашел этот question, но он был слишком специфичным и не содержал никаких указаний относительно того, как идентифицировать такие случаи.
Ответы
Ответ 1
Когда следует избегать использования идиомы копирования и свопинга?
Когда вы можете доказать, что наивная копия безопасна и быстрее, чем swap
.
Вы можете определить случай, когда нет указателей-членов (ни интеллектуальных, ни сырых), которые являются собственными объектами, и то же самое верно для всех объектов-членов.
И когда его "нельзя использовать" вообще?
Копировать-и-swap нельзя использовать, если тип не swappable.
Чтобы быть заменяемым, тип должен быть как конструктивным, так и переносимым, или вы должны определить функцию члена swap
или функцию друга.
Ответ 2
Ваша ссылка, описывающая потенциальные реализации оператора присваивания, описываемого class_name& class_name::operator=(class_name)
как:
Типичное объявление оператора присваивания копий при использовании идиомы копирования и свопинга
И class_name& class_name::operator=(const class_name&)
как:
Типичное объявление оператора присваивания копии при невозможности использования идиомы копирования и свопинга
В принципе, мы всегда хотели бы использовать возможность копирования и свопинга, если это возможно, как указано в отличном ответе на ваш связанный вопрос, поскольку он пройдет самообслуживание, тест соответствия.
Итак, теперь вопрос в том, почему соглашение, упомянутое в http://www.cppreference.com?
Скажем, я реализую конструктор копирования для виртуального класса, и я хочу дать понять всем, кто унаследует, что они должны использовать идиому копирования и свопинга. Как мне это сделать? Я мог бы помочь им, выполнив для них копию при первом вызове:
class_name& class_name::operator=(class_name)
Это копия по значению, поэтому разработчик любых дочерних классов увидит, что я уже сделал копию для них, поэтому все, что им нужно сделать, это обмен.
Теперь, если бы у меня был class_name
, в котором содержался член, который не мог быть скопирован, например, что, если мой класс имеет unique_ptr
, так что он не может быть создан для копирования. Я могу указать, что, не делая аргумент copy по значению для оператора присваивания, например:
class_name& class_name::operator(const class_name&)
Указание на выполнение любого дочернего класса для обеспечения достаточной проверки для прохождения теста самообучения.