La règle des 5 stipule que si une classe possède un destructeur, un constructeur de copie, un constructeur d'affectation de copie, un constructeur de déplacement ou un constructeur d'affectation de déplacement déclarés par l'utilisateur, alors elle doit posséder les 4 autres.
Mais aujourd'hui, je me suis rendu compte que je n'ai jamais eu besoin d'un destructeur, d'un constructeur de copie, d'un constructeur d'affectation de copie, d'un constructeur de déplacement ou d'un constructeur d'affectation de déplacement définis par l'utilisateur.
D'après moi, les constructeurs et destructeurs implicites fonctionnent parfaitement pour les structures de données agrégées. Cependant, les classes qui gèrent une ressource ont besoin de constructeurs/destructeurs définis par l'utilisateur.
Cependant, toutes les classes de gestion des ressources ne peuvent-elles pas être converties en une structure de données agrégée utilisant un pointeur intelligent ?
Exemple :
// RAII Class which allocates memory on the heap.
class ResourceManager {
Resource* resource;
ResourceManager() {resource = new Resource;}
// In this class you need all the destructors/ copy ctor/ move ctor etc...
// I haven't written them as they are trivial to implement
};
vs
class ResourceManager {
std::unique_ptr<Resource> resource;
};
Maintenant, l'exemple 2 se comporte exactement comme l'exemple 1, mais tous les constructeurs implicites fonctionnent.
Bien sûr, vous ne pouvez pas copier ResourceManager
mais si vous souhaitez un comportement différent, vous pouvez utiliser un autre pointeur intelligent.
Le fait est que vous n'avez pas besoin de constructeurs définis par l'utilisateur lorsque les pointeurs intelligents en ont déjà, de sorte que les constructeurs implicites fonctionnent.
La seule raison que je verrais pour avoir des constructeurs définis par l'utilisateur serait quand :
-
vous ne pouvez pas utiliser de pointeurs intelligents dans du code de bas niveau (je doute fortement que ce soit jamais le cas).
-
vous implémentez les pointeurs intelligents eux-mêmes.
Cependant, dans un code normal, je ne vois aucune raison d'utiliser des constructeurs définis par l'utilisateur.
Est-ce que je rate quelque chose ici ?