A partir de ce message de Medinoc un poil retravaillé par moi, voici une nouvelle entrée dans la FAQ. Des avis ?

Lorsqu'une classe doit gérer de la mémoire, il est d'usage de la mettre sous une forme que l'on appel forme canonique. Mais il existe plusieurs variantes de la forme canonique, selon que la classe soit copiable, modifiable, swappable...

Classe non-copiable, non-assignable, mais swappable:
  • Constructeur
  • Constructeur par copie: privé, non-défini
  • operator= : privé, non-défini
  • Swap() + spécialisation de std::swap<>
  • Destructeur


Classe copiable, mais immuable (non-assignable, non-swappable)
  • Constructeur
  • Constructeur par copie
  • operator= : privé, non-défini
  • Destructeur


Classe pleinement copiable, assignable, swappable:
  • Constructeur
  • Constructeur par copie
  • operator= : utilise idiome copy-and-swap
  • Swap() + spécialisation de std::swap<>
  • Destructeur


De plus, le destructeur n'a pas forcément à être virtuel, cela dépent des cas. Si l'héritage est publique et que la classe de base va servir en tant qu'interface, alors, le destructeur doit être virtuel. Par contre si l'héritage est protégé/privé et qu'il sert à réutiliser du code sans notion d'interface et de polymorphisme, alors le destructeur de la classe de base doit être protégé et non-virtuel.

Enfin pour les constructeurs, il est souvent préconisé de les faire protégés pour toutes les classes non-terminale, seules les classes terminales doivent être instanciables.
PS: on peut aussi rajouter ce qu'est une classe à sémantique de valeur ( de medinoc):
On dit d'une classe qu'elle a une sémantique de valeur si deux objets situés à des adresses différentes, mais au contenu identique, sont considérés égaux.
Et pour celle à sémantique d'entité (de moi):
A l'inverse, une classe a une sémantique d'entité si tous les objets de cette classe sont nécéssairement deux à deux distincts.