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 :

shared_ptr et dependance cyclique


Sujet :

C++

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 3
    Par défaut shared_ptr et dependance cyclique
    Bonjour à tous et merci d'avance pour votre aide

    J'ai un problème dans mon code, car j'ai besoin de d'avoir deux classe qui se contienne l'une l'autre sous forme de shared_ptr. J'ai essayer d'utiliser un weak_ptr pour casser la dépendance, mais je le fais mal, le programme crash quand je le créer.

    Je suis en train de faire un pattern state, d'ou la dépendance.

    Voici mon code.

    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
    18
    19
    20
    21
    22
    23
    #ifndef CCLIENT_H_INCLUDED
    #define CCLIENT_H_INCLUDED
     
    #include <memory>
    #include "etat.h"
     
    class client
    {
    private:
     
        std::shared_ptr<etat> etat1_;
        std::shared_ptr<etat> etat2_;
        std::shared_ptr<etat> etatCourant_;
     
    public:
        client();
        void action();
        void setEtatCourant(std::shared_ptr<etat> etat);
        std::shared_ptr<etat> getEtat1();
        std::shared_ptr<etat> getEtat2();
    };
     
    #endif // CCLIENT_H_INCLUDED
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #include "client.h"
    #include "etat.h"
     
    client::client() : etat1_(new etat(this)), etat2_(new etat(this))
    {
        etatCourant_ = etat1_;
    }
     
    void client::action()
    {
        etatCourant_->action();
    }
     
    void client::setEtatCourant(std::shared_ptr<etat> etat)
    {
        etatCourant_ = etat;
    }
     
    std::shared_ptr<etat> client::getEtat1()
    {
        return etat1_;
    }
     
    std::shared_ptr<etat> client::getEtat2()
    {
        return etat2_;
    }
    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
    18
    19
    #ifndef CETAT_H_INCLUDED
    #define CETAT_H_INCLUDED
     
    #include <memory>
     
    class client;
     
    class etat
    {
    private:
     
        std::weak_ptr<client> client_;
     
    public:
        etat(client* c);
        void action();
    };
     
    #endif // CETAT_H_INCLUDED
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include "client.h"
    #include "etat.h"
    #include <iostream>
     
    etat::etat(client* c) : client_ (std::shared_ptr<client>(c))
    {
    }
     
    void etat::action()
    {
        client_.lock()->setEtatCourant(client_.lock()->getEtat2());
        client_.reset();
    }

  2. #2
    Membre actif
    Homme Profil pro
    Ingénieur
    Inscrit en
    Octobre 2006
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Transports

    Informations forums :
    Inscription : Octobre 2006
    Messages : 48
    Par défaut
    Bonsoir,

    La réponse est dans la FAQ :
    http://cpp.developpez.com/faq/cpp/?p...-une-a-l-autre

    Le fait que l'ont ait des shared_ptr au lieu d'un pointeur nu ne change pas grand chose à l'histoire. Il faut utiliser au minimum une déclaration anticipée!

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 3
    Par défaut
    Si tu regarde bien mon code, j'ai déjà résolu se problème, donc l'erreur ne viens pas de là.

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Après un coup d'oeil rapide:
    Quand tu crées un shared_ptr à partir d'un weak_ptr (à l'aide de lock), cette création peut échouer, si l'objet pointé a été détruit entre temps. Dans ce cas, lock retourne un shared_ptr nul. Tu dois toujours tester la valeur retournée par lock avant de l'utiliser.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 3
    Par défaut
    Après ton conseil, j'ai changer mon code cette façon

    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
    18
    #include "client.h"
    #include "etat.h"
    #include <iostream>
     
    etat::etat(client* c)
    {
        std::weak_ptr<client> client_(std::shared_ptr<client>(c));
    }
     
    void etat::action()
    {
        std::shared_ptr<client> temp(client_.lock());
        if(temp)
        {
            temp->setEtatCourant(temp->getEtat2());
        }
        client_.reset();
    }
    Mais j'ai toujours un problème, client_.lock() me renvoie null quand je l’appelle dans action, alors que j'aurais aimer qu'il me renvoie un shared_ptr. J'imagine que c'est donc mon initialisation que est mauvaise, quelqu'un pourrais m'expliquer pourquoi?

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par Trii42 Voir le message
    Après ton conseil, j'ai changer mon code cette façon

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    etat::etat(client* c)
    {
        std::weak_ptr<client> client_(std::shared_ptr<client>(c));
    }
    Là, tu définis une variable locale ayant le même nom que ta donnée membre...

    Mais sinon, il y a un autre soucis : Tu crées un shared_ptr quand tu associe un état à un client. Donc si tu associe 2 états à un même client, il y aura 2 familles de shared_ptr, chacune avec son propre compteur de référence, qui se feront concurrence pour effacer la donnée...

    Il vaudrait mieux que le constructeur d'etat prenne en paramètre un shared_ptr déjà existant. Tu peux regarder du côté de shared_from_this, par exemple dans cette doc : http://loic-joly.developpez.com/tuto...mart-pointers/ (tu est dans le cas où tu voudrais un shared_from_this dans le constructeur).
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

Discussions similaires

  1. Dependence cyclique A+B+C est different de C+B+A
    Par Goupil dans le forum Langage
    Réponses: 4
    Dernier message: 07/09/2006, 14h03
  2. dependances cycliques
    Par Raumfahrerralf dans le forum C++
    Réponses: 14
    Dernier message: 12/03/2005, 19h10
  3. Les différences entre association et dépendance ?
    Par sephile dans le forum Diagrammes de Classes
    Réponses: 3
    Dernier message: 12/01/2005, 13h43
  4. [JBuilder X][Exécutable] Gestion de dépendances
    Par marevinc dans le forum JBuilder
    Réponses: 3
    Dernier message: 16/11/2004, 09h08
  5. Packages - problème de dependances
    Par Invité dans le forum Administration système
    Réponses: 3
    Dernier message: 14/06/2004, 10h46

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