IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

La règle pour bien construire ses destructeurs en C++ ?


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 31
    Points : 13
    Points
    13
    Par défaut La règle pour bien construire ses destructeurs en C++ ?
    Bonjour à tous,

    J’ai un code qui plante au moment où le destructeur de l’objet est appelé. Je dois dire que je n’ai jamais trop eu à faire attention à l’écriture de mes destructeurs jusqu’à présent, les destructeurs de c(ainsi que les constructeurs de copie d’ailleurs) par défaut ayant toujours suffit, alors c'est peut-être le moment où jamais.



    En ce moment je travaille sur une architecture assez complexe où des classes sont dérivées dans tous les sens et contienent souvent des pointeurs sur d’autres lasses. Je me suis aperçu que les constructeurs de copie avaient à être repris (pour bien prendre en compte ce qui se passait au moment de la copie des pointeurs membres de ma classe principale).



    Au niveau du destructeur qui me pose un problème, ce que je vois avec le débogueur au moment où le destructeur de ma classe principale est appelé, qu’il passe dans un autre destructeur au préalable, ce dernier effectuant un delete de pointeurs.



    En déboguant step à step, je m’aperçois qu’à un moment, le destructeur qui est appelé en intermédiaire, cherche à deleter une variable (un pointeur) qui est déjà devenue le pointeur NULL. Je ne vois pas pour l’instant à quel moment il a pu devenir nul et pourquoi !



    D’ailleurs je comprends même pas clairement pourquoi le destructeur intermédiaire est appelé !



    Alors ma question sera : c’est quoi la vraie règle pour ne pas se planter quand on écrit ses destructeurs (notamment quand il y a des pointeurs dans les classes) et c’est quoi la règle d’appel qui s’exécute au moment de la destruction quand on travaille sur des classes qui héritent d’autres?



    Salut, merci.

  2. #2
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Le corps du destructeur est executé, puis les destrcuteur des attributs sont executés, puis les destructeurs des classes de bases. Tout est détruit dans l'ordre inverse de la construction.

    Pour ton problème, sans code c'est difficil de voir où pourrait se situer le problème.

    La règle, c'est de toujours libérer les ressource qu'on a acquise, ca évite toute fuite. Le RAII permet de grandement simplifier la gestion des ressources dans les couches "supérieure" du code. (la gestion étant encapsulé)

  3. #3
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Si tu alloues dynamiquement des pointeurs dans une classe, il faut gérer explicitement la copie ou l'interdire selon la sémantique de la classe. En effet, le constructeur de copie synthétisé par le compilateur génère une copie bit à bit des objets. Donc si tu copié un objet qui gère un pointeur, tu vas te retrouver avec deux objet dont des membres vont pointer vers la même adresse mémoire. Lors de la destruction du premier objet(en supposant que tu libères bien ta mémoire dans le destructeur) , ca se passe bien, lors de la destruction du second, boom.

    Je laisse koala écrire une prose plus longue et détaillée.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    La F.A.Q : Le RAII
    Tutoriel : Gérer ses ressources de manière robuste en C++ par Aurélien Regat-Barrel
    La solution : ne pas utiliser de pointeurs nus mais privilégier les pointeurs intelligents : Présentation des pointeurs intelligents en C++ par Loïc Joly et Boost.SmartPtr : Les pointeurs intelligents de Boost par Matthieu Brucher

  5. #5
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    Je rajouterais aussi que tu ne devrais écrire ton destructeur que si tu utilises une gestion dynamique de mémoire, une gestion des fichiers et réseaux. Sinon laisser le compilateur le faire à notre place, il le fera toujours mieux que nous actuellement.
    Homer J. Simpson


  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Astraya Voir le message
    Je rajouterais aussi que tu ne devrais écrire ton destructeur que si tu utilises une gestion dynamique de mémoire, une gestion des fichiers et réseaux. Sinon laisser le compilateur le faire à notre place, il le fera toujours mieux que nous actuellement.
    Pour ça aussi, il y a la F.A.Q. : Qu'est-ce que la forme canonique orthodoxe de Coplien ? et les cinq suivantes

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Salut,

    pour ma part, si dans un constructeur j'ai un new alors dans le destructeur j'ai un delete. Maintenant, si je copie un pointeur (vers une classe) et que je ne fais que la copie du pointeur (donc pas de new) alors il n'y a pas besoin de faire de delete.

    A chaque new correspond un delete

    Sinon, comme dit précédemment par 3DArchi, utiliser les smart pointeurs et le problème est réglé.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 31
    Points : 13
    Points
    13
    Par défaut
    Salut, merci bcp pour toutes vos contributions. A voir la F.A.Q et le message de salseropom, il se pourrait bien que mon probème vienne du manque de rigueur du code au regard des "new" et des copies locales... pour mettre en ligne des bouts de source, ce serait bien volontiers (!) mais je saurais franchement po trop quoi mettre (code de plusieurs dizaines de milliers de lignes....)
    Je vous remercie en tout cas.

  9. #9
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Héritage et copies ?
    J'interdirai purement et simplement les copies. Une classe qui est dans une hiérarchie n'a que rarement besoin d'être copiée -- sans parler des complications sous-jacentes.

    Sinon, la FAQ est un bon point de départ.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

Discussions similaires

  1. Outils pour bien construire ses tables ?
    Par hellomorld dans le forum Langage SQL
    Réponses: 0
    Dernier message: 18/05/2013, 17h37
  2. Bien construire ses classes
    Par hunter99 dans le forum C++
    Réponses: 3
    Dernier message: 25/12/2007, 02h31
  3. Bien faire ses sauvegardes
    Par Pigoulou dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 04/01/2005, 08h20
  4. Règles pour les #include
    Par julian_ross dans le forum MFC
    Réponses: 2
    Dernier message: 24/02/2004, 09h57
  5. [mise en page] pour bien indenter son code
    Par bihorece dans le forum C++Builder
    Réponses: 4
    Dernier message: 06/08/2003, 16h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo