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 :

Déclaration anticipée ou destructeur par défaut?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut Déclaration anticipée ou destructeur par défaut?
    Bonjour,

    lorsque vous déclarez une nouvelle classe, privilégiez-vous la version avec déclaration anticipée des types des données membres
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class Bar;
    class Foo
    {
     
    public:
     
      Foo(int arg) : m_data(new Bar(arg))
      {}
     
      ~Foo()
      { delete m_data; }
     
    private:
     
      Bar* m_data;
     
    };
    ou la version avec destructeur par défaut?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include "bar.hpp"
    class Foo
    {
     
    public:
     
      Foo(int arg) : m_data(arg)
      {}
     
    private:
     
      Bar m_data;
     
    };
    J'utilise souvent la seconde pour gagner en performance sur la destruction des objets mais je me demande si ce n'est pas un mauvais réflexe.

    Quel choix faites-vous en pratique et pourquoi?

    Merci pour vos réponses!

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    La seconde solution a le mérite de respecter les principes RAII, on aura donc moins de risques d'avoir des fuites mémoires.
    De plus, tu ne devrais pas avoir de problèmes du type :
    • ma classe A contient un B ;
    • ma classe B contient un A ;

    Car cela entraînerait une boucle infinie.

    Pour la première solution, on préférera utiliser des pointeurs intelligents, mais dans ce cas là on ne devrait pas pouvoir utiliser de déclaration anticipée (*) ce qui serait utile uniquement dans le cas où l'instance de Bar peut changer dans ta classe Foo.
    Par contre, si tu te retrouves dans le cas :
    • ma classe A peut contenir un B ;
    • ma classe B peut contenir un A ;

    Tu sera obliger de passer par un pointeur nu si ne ne me trompe.

    * après de rapides tests, il est possible d'utiliser des pointeurs intelligents avec une déclaration anticipée, pourtant il me semblait que cela posait problème (?).
    Alors je ne sais pas si j'ai rêvé ou si le problème existait avec g++ < 4.9 (?).

  3. #3
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut
    Salut Neckara,

    merci beaucoup pour ta réponse.

    Dans les deux cas, le RAII est respecté donc ça ne me paraît pas être un bon critère pour trancher.

    Le problème des définitions circulaires est effectivement résolu par les déclarations anticipées mais ma question porte plutôt sur le meilleur choix à faire en l'absence de ce problème (puisque dans le cas contraire il n'y a plus de choix).
    On pourrait privilégier la solution qui permet d'éliminer un problème seulement potentiel mais c'est une mauvaise pratique en général (YAGNI).
    Si on suivait ce principe, tous les destructeurs seraient virtuels.

    La question des pointeurs intelligents ne concerne pas directement mon problème.

    Ma question porte réellement sur le meilleur choix à faire quand ce choix se présente effectivement.

  4. #4
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par Aleph69 Voir le message
    Dans les deux cas, le RAII est respecté donc ça ne me paraît pas être un bon critère pour trancher.
    La première méthode n'est pas du RAII car tu ne "lie" pas la durée de vie l'objet à la durée de vie de ton instance. En effet, tu libères toi-même la ressource "à la main" dans le destructeur.

    Ainsi, si un jour tu oublies de faire un delete (ça peut arriver même aux plus expérimentés), tu auras une fuite de mémoire ou une ressource non libérée.

  5. #5
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut
    Le principe RAII consiste justement à acquérir les ressources à l'initialisation (constructeur) et à les libérer à la destruction.
    L'exemple
    n'aboutit à aucune fuite mémoire.
    Je ne peux pas oublier de "delete" puisque je n'en ai pas besoin.

  6. #6
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par Aleph69 Voir le message
    Je ne peux pas oublier de "delete" puisque je n'en ai pas besoin.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      Foo(int arg) : m_data(new Bar(arg))
      {}
     
      ~Foo()
      { delete m_data; }
    Ici, tu peux oublier le "delete".

Discussions similaires

  1. Réponses: 2
    Dernier message: 23/05/2007, 14h05
  2. [TListBox] Selection par défaut
    Par Nuts07 dans le forum Composants VCL
    Réponses: 8
    Dernier message: 12/05/2003, 10h00
  3. Couleur de sélection par défaut
    Par sicard_51 dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 20/04/2003, 23h35
  4. [SWING][FONT] choisir la police par défaut
    Par narmataru dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 21/02/2003, 10h35
  5. Retour au mode texte par défaut
    Par coca dans le forum x86 16-bits
    Réponses: 6
    Dernier message: 12/12/2002, 17h22

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