Да. Есть два распространенных варианта. Один из них, который обычно не рекомендуется, - это operator=
явный вызов конструктора копирования:
MyClass(const MyClass& other)
{
operator=(other);
}
Однако предоставление товара operator=
- это проблема, когда дело касается старого состояния и проблем, возникающих из-за самостоятельного назначения. Кроме того, все элементы и базы сначала инициализируются по умолчанию, даже если они должны быть назначены from other
. Это может быть не действительным даже для всех членов и баз, и даже там, где это допустимо, оно семантически избыточно и может быть практически дорогостоящим.
Все более популярным решением становится реализация operator=
с использованием конструктора копирования и метода подкачки.
MyClass& operator=(const MyClass& other)
{
MyClass tmp(other);
swap(tmp);
return *this;
}
или даже:
MyClass& operator=(MyClass other)
{
swap(other);
return *this;
}
swap
Функция , как правило , просто напишите как это просто обменивает собственность внутренностей и не должно очистить существующее состояние или выделять новые ресурсы.
Преимущества идиомы копирования и обмена заключаются в том, что она автоматически обеспечивает безопасное самоназначение и, при условии, что операция обмена не выполняется, также строго безопасна в отношении исключений.
Для обеспечения строгой защиты от исключений «рукописный» оператор присваивания обычно должен выделить копию новых ресурсов перед отменой выделения старых ресурсов правопреемника, чтобы в случае возникновения исключения при распределении новых ресурсов старое состояние все еще могло быть возвращено в . Все это бесплатно с копированием и заменой, но, как правило, более сложное и, следовательно, подверженное ошибкам выполнение с нуля.
Единственное, о чем следует быть осторожным, - это убедиться, что метод подкачки является истинным свопом, а не методом по умолчанию, std::swap
который использует сам конструктор копирования и оператор присваивания.
Обычно используется поэлементный swap
. std::swap
работает, и для всех основных типов и типов указателей гарантируется отсутствие выброса. Большинство интеллектуальных указателей также можно поменять местами с гарантией отсутствия выброса.