Sim. Existem duas opções comuns. Uma - que geralmente é desencorajada - é chamar operator=
explicitamente o do construtor de cópia:
MyClass(const MyClass& other)
{
operator=(other);
}
No entanto, fornecer um bem operator=
é um desafio quando se trata de lidar com o antigo estado e com as questões decorrentes da auto-atribuição. Além disso, todos os membros e bases são inicializados por padrão primeiro, mesmo se eles forem atribuídos a from other
. Isso pode não ser válido para todos os membros e bases e, mesmo quando é válido, é semanticamente redundante e pode ser praticamente caro.
Uma solução cada vez mais popular é implementar operator=
usando o construtor de cópia e um método de troca.
MyClass& operator=(const MyClass& other)
{
MyClass tmp(other);
swap(tmp);
return *this;
}
ou mesmo:
MyClass& operator=(MyClass other)
{
swap(other);
return *this;
}
Uma swap
função normalmente é simples de escrever, pois apenas troca a propriedade dos componentes internos e não precisa limpar o estado existente ou alocar novos recursos.
As vantagens do idioma de cópia e troca é que ele é automaticamente seguro para auto-atribuição e - contanto que a operação de troca seja ilimitada - também é fortemente seguro para exceções.
Para ser totalmente seguro contra exceções, um operador de atribuição escrita 'à mão' normalmente tem que alocar uma cópia dos novos recursos antes de desalocar os recursos antigos do cessionário, de modo que se ocorrer uma exceção ao alocar os novos recursos, o estado antigo ainda pode ser devolvido para . Tudo isso vem de graça com o copy-and-swap, mas normalmente é mais complexo e, portanto, sujeito a erros para fazer do zero.
A única coisa a se ter cuidado é ter certeza de que o método swap é um swap verdadeiro, e não o padrão std::swap
que usa o próprio construtor de cópia e operador de atribuição.
Normalmente, um memberwise swap
é usado. std::swap
funciona e é 'no-throw' garantido com todos os tipos básicos e tipos de ponteiro. A maioria dos ponteiros inteligentes também pode ser trocada com uma garantia de não lançamento.