1 - Безопасны ли методы и конструкторы, реализованные выше для класса Bar?Используя копирование и обмен для Foo, убедитесь, что при назначении или копировании Bar не может быть никакого вреда?
Относительно copy-ctor: это всегда безопасно (все или ничего),Он либо завершает (все), либо выдает исключение (ничего).
Если ваш класс состоит только из одного члена (то есть без базовых классов), оператор присваивания будет так же безопасен, какчто из класса члена.Если у вас более одного члена, оператор присваивания больше не будет «все или ничего».Оператор присваивания второго члена может выдать исключение, и в этом случае объект будет назначен «на полпути».Это означает, что вам нужно снова реализовать функцию копирования и замены в новом классе, чтобы получить назначение «все или ничего».
Однако это все равно будет «безопасным», в том смысле, что вы не потеряетеРесурсы.И, конечно, состояние каждого члена в отдельности будет согласованным - просто состояние нового класса не будет согласованным, поскольку один член был назначен, а другой - нет.
2 - ПередачаАргумент по ссылке в конструкторе копирования и в swap является обязательным?
Да, передача по ссылке обязательна.Конструктор копирования - это тот, который копирует объекты, поэтому он не может принимать свой аргумент по значению, поскольку это будет означать, что аргумент должен быть скопирован.Это привело бы к бесконечной рекурсии.(Copy-ctor будет вызываться для аргумента, что будет означать вызов copy-ctor для аргумента, что будет означать ...).Для свопа причина в другом: если вы передадите аргумент по значению, вы никогда не сможете использовать своп для реального обмена содержимым двух объектов - «целью» свопа будет копия объекта, изначально переданного,который будет немедленно уничтожен.
3 - Правильно ли говорить, что когда аргумент operator = передается по значению, конструктор копирования вызывается для этого аргумента, чтобы сгенерировать временную копию объектаи что именно эта копия затем поменялась местами с * this?Если бы я прошел по ссылке в операторе = у меня была бы большая проблема, верно?
Да, все верно.Тем не менее, также довольно распространено взять аргумент с помощью reference-to-const, создать локальную копию и затем заменить ее локальной копией.Однако способ by reference-to-const имеет некоторые недостатки (он отключает некоторые оптимизации).Если вы не реализуете функцию копирования и замены, вам, вероятно, следует перейти по ссылке на const.
4 - Существуют ли ситуации, в которых эта идиома не удаетсяобеспечить полную безопасность при копировании и назначении Foo?
Ничего из того, что я знаю.Конечно, с многопоточностью всегда можно что-то потерпеть (если не правильно синхронизированы), но это должно быть очевидно.