# Regra dos três (C++)

A regra dos três e a regra dos cinco são regras práticas em C++ para a construção de código seguro contra exceções e para formalizar a gestão de recursos. Isso é feito pela prescrição de como os membros padrões de uma classe devem ser usados para realizar esta tarefa de forma sistemática.

## Regra dos Três

A regra dos três (também conhecida como Rule of Three, Law of The Big Three ou The Big Three em inglês) é uma regra prática em C ++ (anterior a C++11) que afirma que, se uma classe define um (ou mais) dos seguintes membros, provavelmente deve definir explicitamente todos os três:
* destrutor
* construtor de cópia
* operador de cópia
Essas três funções são membros especiais de uma classe em C++. Se uma dessas funções for usada sem primeiro ser declarada pelo programador, ela será implicitamente implementada pelo compilador com a seguinte semântica padrão:
* Destrutor - Chama os destrutores de todos os membros da classe do objeto.
* Construtor de cópia - Constrói todos os membros do objeto a partir dos membros correspondentes do argumento sendo copiado. Chama os construtores de cópia de cada membro e faz uma atribuição simples para os membros de tipos não-classe (por exemplo, int ou ponteiros).
* Operador de cópia - Copia todos os membros do objeto dos membros correspondentes do argumento, chamando seus operadores de cópia e fazendo uma atribuição simples de todos os membros do tipo não classe (por exemplo, int ou ponteiro).
A Regra dos Três afirma que se uma dessas funções tiver que ser definida, isso significa que a versão gerada pelo compilador não se ajusta às necessidades da classe em questão e então provavelmente as outras funções padrões não se ajustarão. O termo "Regra de três" foi criado por Marshall Cline em 1991.
Uma alteração a essa regra é que, se a classe for projetada de forma que RAII (Aquisição de Recurso é Inicialização) seja usada para todos os membros (não triviais), o destrutor pode ser deixado indefinido (também conhecido como The Law of the Big Two). Um exemplo pronto dessa abordagem é o uso de ponteiros inteligentes em vez de ponteiros simples.
Como construtores gerados implicitamente e operadores de cópia simplesmente copiam todos os membros da classe ("shallow copy"), deve-se definir construtores de cópia explícita e operadores de cópia para classes que encapsulam estruturas de dados complexas ou possuem referências externas, como ponteiros. Se o comportamento padrão ("cópia superficial") for realmente o pretendido, uma definição explícita, embora redundante, será um "código autodocumentado" indicando que era uma intenção e não uma omissão.

## Regra dos Cinco

Com o advento de C++11 a regra dos três pode ser ampliado para a regra dos cinco (rule of five, também conhecida como rule of big five) pois C++11 implementa semântica do movimento, permitindo que um objeto agarre (ou roube) dados de objetos temporários. O exemplo a seguir também mostra os novos membros de movimento: construtor de movimento e operador de movimento. Consequentemente, para a regra dos cinco, temos os seguintes membros especiais:
* destruidor
* construtor de cópia
* operador de cópia
* construtor de movimento
* operador de movimento
Situações existem onde as classes podem precisar de destrutores, mas não podem implementar de forma sensata construtores e operadores de cópia e movimentação. Em C ++ 11, isso pode ser simplificado especificando explicitamente os cinco membros como "default".