2015-11-16 4 views
12

После прочтения this о копирования и обмена идиомы я прочитал this, который говорит, что в пункте (2):Когда копирование и своп идиома не применяется

class_name & class_name :: operator= (const class_name &)  (2)  

(2) Типовой декларации оператора присваивания копировального при копирования и замены идиома не может быть использована

когда следует избегать использования копирования и своп идиома?

И когда он «не может быть использован» вообще?

Существуют ли случаи реальной жизни, когда как копия, так и замена и правило-ноль не применимы?

Я нашел это question, но он был слишком конкретным и не содержал никаких указаний относительно того, как идентифицировать такие случаи.

+0

Как правило, копирование и своп * легко * и * безопасно *, но, возможно, не оптимально с точки зрения скорости. Например, присваивая два контейнера из миллиона элементов, вероятно, быстрее выполнить миллион заданий, чем выполнить миллионы конструкций и миллион разрушений. –

+3

@ user2079303 спасибо, что приговор был пьян, ему пришлось идти домой. Надеюсь, теперь это ясно. – Darius

+1

Реальные случаи жизни, когда копия/своп убивает вашу производительность: http://stackoverflow.com/a/25942402/576911 –

ответ

7

Когда нам следует избегать использования идиомы с копией и заменой?

Если вы можете доказать, что наивная копия безопасна и быстрее, чем swap.

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

И когда он «не может быть использован» вообще?

Copy-and-swap не может использоваться, если тип не swappable.

Чтобы быть заменяемым, тип должен быть либо конструктивным, либо перемещаемым, либо вы должны определить функцию члена swap или функцию друга.

2

Ваша ссылка с описанием возможных реализаций оператора присваивания описаны class_name& class_name::operator=(class_name) как:

Типичное объявление оператора присваивания копии, когда копирование и своп идиома может быть использован

И class_name& class_name::operator=(const class_name&) как :

Типичное объявление оператора присваивания копии при невозможности использования идиомы копирования и свопинга

В основном мы всегда хотим использовать скопировать и своп, когда это возможно, как уже упоминалось в excellent answer to your linked question, потому что он будет проходить тест на себя задание.

Так что теперь вопрос в том, почему конвенция упомянута на http://www.cppreference.com?

Предположим, что я реализую конструктор копирования для виртуального класса, и я хочу дать понять всем, кто наследует, что они должны использовать идиому копирования и свопинга. Как мне это сделать?Я мог бы помочь им, делая копию для них в первоначальном вызове:

class_name& class_name::operator=(class_name) 

Это копия по значению, поэтому реализатор всех дочерних классов будет видеть, что я уже сделал копию для них, так что все им нужно будет поменять местами.

Теперь, если бы у меня был class_name, который содержал элемент, который не мог быть скопирован, например, что, если мой класс имеет unique_ptr, так что он не может быть создан для копирования. Я могу указать, что не сделать копию с помощью значения аргумента оператора присваивания, например:

class_name& class_name::operator(const class_name&) 

Указав будет на реализатора любых дочерних классов, чтобы обеспечить достаточную проверку делается передать себя -адаптация.