Checklist para escrever construtor de cópia e operador de atribuição em C ++
-
03-07-2019 - |
Pergunta
Por favor, escreva uma lista de tarefas que uma necessidade construtor de cópia e operador de atribuição para fazer em C ++ para manter a segurança de exceção, vazamentos de memória evitar etc.
Solução
Em primeiro lugar ter certeza que você realmente precisa cópia de apoio. Na maioria das vezes não é o caso, e desativando, assim, tanto é o caminho a percorrer.
Às vezes, você ainda precisa fornecer a duplicação em uma classe a partir de uma hierarquia polimórfica, nesse caso: desativar o operador de atribuição, escrever um construtor (protegida?) Copiar, e fornecer uma função de clone virtual ()
Caso contrário, no caso você está escrevendo uma classe de valor, você está de volta para a terra da Canonical Forma de Coplien Orthogonal. Se você tem um membro que não pode ser trivialmente copiado, você precisará fornecer uma cópia-construtor, um destruidor, uma atribuição do operador e um construtor padrão. Esta regra pode ser refinado, ver, por exemplo: a lei do Big Two
Eu também recomendo dar uma olhada em C ++ FAQ sobre operadores de atribuição , e ao copiar-e-swap idioma e em GOTW .
Outras dicas
As versões do compilador gerado trabalhar na maioria das situações.
Você precisa pensar um pouco mais difícil sobre o problema quando o seu objeto contém um ponteiro RAW (um argumento para não ter ponteiros RAW). Então você tem um ponteiro RAW, a segunda questão é que você possui o ponteiro (ele está sendo eliminado por você)? Se sim, então você terá de aplicar a regra de 4.
Possuir mais de um ponteiro RAW torna-se cada vez mais difícil de fazer corretamente (O aumento da complexidade não é linear quer [mas isso é observacional e eu tenho há estatísticas reais para apoiar essa afirmação up]). Então, se você tiver mais de 1 ponteiro RAW pensar em envolver cada um em sua própria classe (alguma forma de ponteiro inteligente).
Regra de 4: Se um objeto é o proprietário de um ponteiro RAW, então você precisa definir as seguintes 4 membros para se certificar de que você lidar com o gerenciamento de memória corretamente:
- Construtor
- Construtor de cópia
- Operador de atribuição
- Destructor
Como você define estes dependerá das situações. Mas as coisas que atente para:
- Padrão de construção: ponteiro definido como NULL
- Copiar Construtor: Use o Copiar e Ideum Trocar para fornecer ao "Garantia Exceção Strong"
- Operador de atribuição: Verificação para atribuição a auto
- Destructor:. Proteja-se contra exceções que se propagam para fora do destructor
tentar ler isto.
http://www.icu-project.org/docs /papers/cpp_report/the_anatomy_of_the_assignment_operator.html
é uma boa análise do Operador de atribuição
Eu não tenho idéia sobre a exceção com segurança aqui, mas eu ir por este caminho. Vamos imaginar que é um invólucro variedade templated. Espero que ajude:)
Array(const Array& rhs)
{
mData = NULL;
mSize = rhs.size();
*this = rhs;
}
Array& operator=(const Array& rhs)
{
if(this == &rhs)
{
return *this;
}
int len = rhs.size();
delete[] mData;
mData = new T[len];
for(int i = 0; i < len; ++i)
{
mData[i] = rhs[i];
}
mSize = len;
return *this;
}