A quoi servent les destructeurs par défaut?

Je peux comprendre les constructeurs par défaut, car les constructeurs définis par l’utilisateur désactivent ceux générés par le compilateur, rendant l’object non copiable, etc., etc.

Dans le cas du destructeur, hormis le changement de catégorie d’access, à quoi sert-il de définir un destructeur par défaut étant donné qu’aucune fonction membre définie par l’utilisateur ne peut les désactiver (vous ne pouvez pas surcharger les destructeurs de toute façon)?

// Which version should I choose ? struct Example { //1. ~Example() = default; //2. ~Example() {} //3. }; 

Même dans le cas des destructeurs virtuels, leur défaillance ne les rendrait pas anodins, alors à quoi sert-il?

Une des utilisations est de rendre le destructeur protected ou private tout en gardant potentiellement la classe sortingviale: il suffit de la lister après le spécificateur d’access souhaité.

Un autre: lors de l’écriture de classes, certains programmeurs aiment ordonner les fonctions de la classe: par exemple, les constructeurs, puis le destructeur, puis les membres “constants” non const , puis les membres const “accesseurs”, puis static fonctions static . En étant en mesure de explicitement = default le destructeur, vous pouvez le lister dans l’ordre attendu et le lecteur qui le consulte sait qu’il ne peut en exister une autre version mal placée. Dans les grandes classes, cela peut avoir une valeur documentaire / sécurité.

Cela vous donne également quelque chose de concret sur lequel append des commentaires, ce qui peut aider certains outils de documentation à comprendre que les commentaires sont liés à la destruction.

L’exception pour l’omission de destructeurs sortingviaux concerne le destructeur de la classe dérivée , pas le premier. Donc virtual ~Foo() = default; est une construction utile pour conserver le destructeur par défaut, mais le virtualiser.

Fondamentalement, il s’agit de communiquer l’intention, mais elle est plutôt redondante.

Mais si vous utilisez std::unique_ptr tant que membre de la classe, vous devrez déclarer destructor (mais seulement déclarer) dans l’en-tête. Ensuite, vous pouvez lui faire utiliser l’implémentation par défaut dans le fichier source comme ceci:

 MyClass:~MyClass() = default; 

Compte tenu de vos options, je voudrais utiliser le premier ou le troisième.

Comme mentionné par Nikos Athanasiou dans un commentaire, un constructeur par défaut rend le type sortingvialement destructible, contrairement à un type défini par l’utilisateur. Un petit exemple de code le montrera:

 #include  #include  struct A { ~A() = default; }; struct B { ~B() {} }; struct C { ~C() noexcept {} }; int main() { std::cout << std::is_trivially_destructible::value << std::is_trivially_destructible::value << std::is_trivially_destructible::value << std::endl; return 0; } 

Affiche

 100 

En ce qui concerne les destructeurs virtuels, la cohérence avec les non-virtuels et la réponse de Quentin sont des raisons appropriées. Mon conseil personnel est que vous devriez toujours utiliser la valeur par défaut lorsque vous le pouvez, car c'est un moyen de s'en tenir au comportement le plus canonique.