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

Langage C++ Discussion :

unique_ptr, conteneur et factory


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut unique_ptr, conteneur et factory
    Bonjour,

    j'ai encore un peu de mal avec unique_ptr, et j'ai du mal à articuler mes vieux patterns avec.

    Voilà, j'ai un conteneur qui contient des unique_ptr. On va dire que le code est comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Dum;
     
    typedef std::vector<std::unique_ptr<Dum>> MyContainer;
    A côté de ça, j'ai une factory qui me construit des objets de type Dum, on va dire que le code est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class DumFactory
    {
    public:
       static std::unique_ptr<Dum> BuildDum();
    };
    Je voudrais pouvoir créer mon conteneur en 2 temps:
    1. Je définis sa taille (donc j'alloue la mémoire nécessaire pour les unique_ptr)
    2. Je construis chaque élément un par un
    Le code devrait donc ressembler à ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    MyContainer container(size);
    for (auto it=container.begin(); it!=container.end(); ++it) // je ne suis pas encore passé au for_each...
       it->swap( DumFactory::BuildDum() );
    Le problème avec le code ci-dessus, si j'ai bien compris, c'est que le swap n'appelle pas le destructeur de Dum, donc je risque d'avoir des fuites mémoire, non?

  2. #2
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    1/ pourquoi-pas reserve + push_back?

    2/ je ne vois pas quel est le probleme, qu'est-ce que tu voudrais?

  3. #3
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Merci de t'intéresser à mon problème
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    1/ pourquoi-pas reserve + push_back?
    Je pensais que ça revenais au même. Ce n'est pas vrai?

    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    2/ je ne vois pas quel est le probleme, qu'est-ce que tu voudrais?
    Le problème c'est qu'en faisant le swap (dernière ligne de code dans mon premier message), il me semble que ça crée une fuite mémoire. N'est-ce pas le cas?

  4. #4
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par r0d Voir le message
    Merci de t'intéresser à mon problème
    Je pensais que ça revenais au même. Ce n'est pas vrai?
    Ca evite de construire un objet pour le detruire sans en avoir rien fait tout juste apres. (Dans le cas present, un unique_ptr construit par defaut, ca ne doit pas trop couter mais ...)

    Le problème c'est qu'en faisant le swap (dernière ligne de code dans mon premier message), il me semble que ça crée une fuite mémoire. N'est-ce pas le cas?
    Le menage sera fait quand le temporaire sera detruit.

    En passant, pourquoi swap plutot qu'une assignation? La semantique de mouvement, c'est quand meme fait pour eviter ce genre de choses.

  5. #5
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Ca evite de construire un objet pour le detruire sans en avoir rien fait tout juste apres. (Dans le cas present, un unique_ptr construit par defaut, ca ne doit pas trop couter mais ...)
    Effectivement, c'est toujours mieux. Et puis c'est plus propre.


    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    En passant, pourquoi swap plutot qu'une assignation? La semantique de mouvement, c'est quand meme fait pour eviter ce genre de choses.
    Parce que je ne sais pas faire
    C'est ce que je voulais faire, mais je n'y suis pas parvenu, et j'ai fini par penser que ce n'était pas possible.

    Du coup j'ai modifié pas mal mon code en prenant vos remarques en compte, et maintenant ça donne ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    std::vector<std::unique_ptr<Dum>> container;
    // il y a du code entre temps
    container.reserve(size);
    for (int i=0; i<size;++i) // edité, voir messages suivants
       container.push_back( DumFactory::BuildDum() );
    Je trouve que c'est propre, pas spécialement verbeux, et ça me semble robuste. Je commence à apprécier les smart_pointer
    Maintenant il faut que je m'intéresse aux shared_ptr, mais là c'est plus compliqué :/

  6. #6
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    Petit bémol :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    std::vector<std::unique_ptr<Dum>> container;
    // il y a du code entre temps
    container.reserve(size);
    for (int i=0; i<size;++i)
       container.push_back( DumFactory::BuildDum() );
    reserve() ne change pas la taille du container, il ne fait que réserver suffisamment de mémoire pour pouvoir push_backer size éléments sans réallocation nécessaire..

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Citation Envoyé par r0d Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    MyContainer container(size);
    for (auto it=container.begin(); it!=container.end(); ++it) // je ne suis pas encore passé au for_each...
       it->swap( DumFactory::BuildDum() );
    Le problème avec le code ci-dessus, si j'ai bien compris, c'est que le swap n'appelle pas le destructeur de Dum, donc je risque d'avoir des fuites mémoire, non?
    Je ne vois pas de problème dans ce code: Le destructeur n'est pas appelé lors du swap c'est vrai, mais il devrait être appelé lors de la destruction automatique du temporaire, juste après le retour de la fonction.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Je ne vois pas de problème dans ce code: Le destructeur n'est pas appelé lors du swap c'est vrai, mais il devrait être appelé lors de la destruction automatique du temporaire, juste après le retour de la fonction.
    Après l'appel à swap()?

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Oui, je dirais entre l'appel à swap et le ++it.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Fonction polymorphe et conteneur stl.
    Par Captain Fizzou dans le forum SL & STL
    Réponses: 2
    Dernier message: 29/11/2004, 19h13
  2. question générale sur les conteneurs
    Par tut dans le forum C++
    Réponses: 6
    Dernier message: 01/09/2004, 10h11
  3. [Conception][Factory] Packages inheritance
    Par ludovic.fernandez dans le forum Général Java
    Réponses: 5
    Dernier message: 05/07/2004, 17h02
  4. Conteneurs associatifs à clés dupliquées
    Par Christophe Brun dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 04/07/2004, 14h16

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