Partage
  • Partager sur Facebook
  • Partager sur Twitter

Pourquoi voit-on beaucoup de destructeurs vides ?

    7 février 2024 à 18:49:56

    Salut tout le monde !

    Au cours de beaucoup de projets sur lesquels j'ai travaillés en entreprise, il m'ait souvent arrivé de constater que les développeurs avant moi avaient déclarés les destructeurs des classes pour rien :

    MyClass::~MyClass() {}


    Est-ce qu'il y a un intérêt de faire ça ou c'est bel et bien inutile comme je le suppose ?

    En plus, les destructeurs sont déclarés dans des classes qui ne sont pas des classes Base donc il n'y a même pas l'intérêt de déclarer le destructeur pour utiliser le polymorphisme.

    Merci d'avance !

    -
    Edité par ThomasAirain 7 février 2024 à 18:52:31

    • Partager sur Facebook
    • Partager sur Twitter
      7 février 2024 à 21:29:53

      Il y a des cas où c'est nécessaire. Par exemple pour déclarer un destructeur virtuel avant que default existe.

      class A {
      public:
        virtual ~A();
      };
      
      A::~A() {} 

      Mais on va préférer maintenant d'utiliser "= default;" directement dans la déclaration.

      Sinon, il y a aussi le cas des unique_ptr avec les forward declarations, qui provoquaient des erreurs lors que le destructeur était implicite declared implicite defined. https://stackoverflow.com/questions/9954518/stdunique-ptr-with-an-incomplete-type-wont-compile 

      Je vois pas pour l'instant d'autres exemples. Mais disons que c'est potentiellement du code legacy que tu as vu, qui était peut être nécessaire a une époque (ou pas).

      • Partager sur Facebook
      • Partager sur Twitter
        7 février 2024 à 21:36:31

        Ah je ne connaissais pas le cas avec le unique_ptr. Je connaissais le cas avec virtual par contre. C'est pour ça que je me demandais pourquoi un destructeur pouvait être défini comme vide en dehors de ces 2 cas-là.

        • Partager sur Facebook
        • Partager sur Twitter
          7 février 2024 à 21:59:04

          Je vois pas trop d'autres cas.

          Et même, c'est en general une mauvaise chose. Parce qu'un destructeur n'a pas cette signature par défaut, on perd le trivial destructible, le inline, le noexcept. Pour ça que c'est mieux d'utiliser `= default` dans la déclaration. ou le laisser implicite declared.

          -
          Edité par gbdivers 7 février 2024 à 21:59:25

          • Partager sur Facebook
          • Partager sur Twitter
            8 février 2024 à 0:49:38

            Oh bien vu gbdivers ! Je viens de lire aussi que la définition explicite du destructeur empêchait le compilateur de générer les move operations par défaut. Un autre problème facile à éviter.
            • Partager sur Facebook
            • Partager sur Twitter
              8 février 2024 à 7:58:46

              Peut être que les destructeurs vides ont été générés lors de la creation de la classe par un EDI qui a cru bon de fournir aussi un constructeur vide, un constructeur de copie, l'affectation, etc.

              Le genre de trucs qui génère aussi des accesseurs/mutateurs à la pelle.

              • Partager sur Facebook
              • Partager sur Twitter
                8 février 2024 à 14:23:30

                Sinon je pose la question juste par acquis de conscience : on est d'accord que définir le destructeur d'une derived class n'est pas nécessaire si le destructeur de la base class est virtuel ? Dans C++ Primer, la derived class ne contient pas de définition explicite du destructeur mais ils ne disent pas non plus de ne pas définir le destructeur.

                Peut être que la raison pour laquelle les destructeurs sont définis explicitement est que les développeurs pensaient que définir le destructeur de la derived class était requis lorsque le destructeur de la base class était virtuel.

                @michelbillaud Ça ce serait dommage parce que ça créerait du mauvais code qui serait ensuite conservé.

                -
                Edité par ThomasAirain 8 février 2024 à 14:30:27

                • Partager sur Facebook
                • Partager sur Twitter
                  8 février 2024 à 15:05:01

                  ThomasAirain a écrit:

                  Sinon je pose la question juste par acquis de conscience : on est d'accord que définir le destructeur d'une derived class n'est pas nécessaire si le destructeur de la base class est virtuel ? 

                  oui.

                  ThomasAirain a écrit:

                  Peut être que la raison pour laquelle les destructeurs sont définis explicitement est que les développeurs pensaient que définir le destructeur de la derived class était requis lorsque le destructeur de la base class était virtuel.

                  Il faut pas trop te prendre la tête sur les raisons. C'est difficile de savoir ce qu'il s'est passé dans la tête du dev pour faire cela. Des habitudes, des pratiques, qui pouvaient être plus ou moins justifié à un moment donné.

                  A savoir : c'est le genre de chose que clang-tidy peut détecter (et parfois corriger automatiquement). Regarde par exemple https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-equals-default.html 

                  • Partager sur Facebook
                  • Partager sur Twitter
                    8 février 2024 à 15:14:57

                    Merci je vais regarder ça !

                    Juste une chose gbdivers, je viens de lire dans l'item 14 de Effective Modern C++ ceci : "By default, all memory deallocation functions and all destructors—both user-defined and compiler-generated—are implicitly noexcept. There’s thus no need to declare them noexcept. (Doing so doesn’t hurt anything, it’s just unconventional.)"

                    Donc définir explicitement le destructeur ne fait que perdre le inline, le trivial destructible et la génération par défaut des move operations finalement.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      8 février 2024 à 15:44:10

                      ThomasAirain a écrit:

                      Juste une chose gbdivers, je viens de lire dans l'item 14 de Effective Modern C++ ceci : "By default, all memory deallocation functions and all destructors—both user-defined and compiler-generated—are implicitly noexcept. There’s thus no need to declare them noexcept. (Doing so doesn’t hurt anything, it’s just unconventional.)"

                      Donc définir explicitement le destructeur ne fait que perdre le inline, le trivial destructible et la génération par défaut des move operations finalement.

                      Merci, j'avais oublié ca.

                      De toute facon, j'utilise tres peu noexcept.

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Pourquoi voit-on beaucoup de destructeurs vides ?

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      • Editeur
                      • Markdown