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 :

comment pointer sur la meme instance?


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 188
    Points : 51
    Points
    51
    Par défaut comment pointer sur la meme instance?
    Bonjour,

    J'ai la classe A suivante qui possède deux classes filles A1 et A2 :
    A.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class A
    {
    private :
    B* attr1; //B est une classe mère qui possède deux classes filles B1 et B2 
    public:
    A(B*);
    ~A();
    }
    A.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    A::A(B var1)
    {attr1=new B(var1);
    }
     
    A::~A()
    {
    delete attr1;
     
    }
    A1.h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    class A1
    {
    A1(B1);
    }
    A1.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    A1::A1(B1 var)
    {
    this->attr1=new B1(var);
    }
    Dans le main.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    B1 b1("bb",5), 
    A1 a1(b1);
    A1 a2(b1)
    Mon problème :
    je veux que les deux instances avoir la meme b1. quand je fais le test d'egalité suivant a1.attr1=a2.attr1 je ne trouve pas que ces deux instances possèdent la meme b1(Résultat: deux adresses différentes).

    J'essaye de modifier this->attr1=new B1(var); dans le constructeur de A1 à attr1=&var mais cette instruction lance une exception.

    Aidez moi svp et Merci.

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Salut,

    C'est bien simple: si tu veux que deux pointeurs pointent vers une même instance, il faut faire en sorte qu'il n'y ait qu'une instance de l'objet qui soit créée, et transmettre l'adresse de cette dernière

    Mais attention: il faut savoir exactement ce que l'on fait lorsque l'on joue avec les pointeurs et que l'on veut arriver à ce résultat:

    Si l'on n'y prend garde, il est "tres facile" de se retrouver dans des situations embarrassantes, soit parce que l'on perd "toute référence" à l'adresse de l'instance avant d'avoir pu veiller à en libérer correctement la mémoire, avec, comme résultat, une fuite mémoire qui peut, à terme menacer jusqu'à la stabilité complète du système d'exploitation, soit parce que l'on "oublie" de faire en sorte que les différents pointeurs qui pointaient sur une instance donnée soient correctement invalidés, avec comme résultat des comportements indéfinis dont l'origine est souvent difficile à trouver, soit, enfin, parce que l'on essayera de libérer deux fois la mémoire allouée à l'instance, ce qui n'est pas bon non plus.

    Si tu es conscient des risques que tu prends et que tu es malgré tout convaincu qu'il faut que deux instances différentes d'une classe A dispose d'un pointeur vers une instance unique d'une classe B, alors, le plus facile est de travailler de la sorte:
    1. Fournir une déclaration anticipée de la classe B avant de définir ta classe A
    2. déclarer un membre de type "pointeur sur B" dans la classe A
    3. déclarer un constructeur pour ta classe A qui prend, en paramètre, un pointeur sur B et qui assigne l'adresse de ce dernier au membre adéquat
    4. NE SURTOUT PAS invoquer delete sur le membre en question dans la classe A: la gestion de la durée de vie de l'instance de B doit être déléguée à "quelque chose d'autre"
    5. Créer l'instance de la classe B en priorité
    6. transmettre le pointeur vers l'instance de classe B à chaque instance de A pour laquelle tu veux que l'instance B soit partagée.
    7. Veiller à détruire l'instance de B au moment où elle n'est plus nécessaire uniquement et, s'il reste des instances de A qui la manipule, veiller à faire en sorte que leur membre correspondant soit mis à jour afin de pointer sur "NULL" (nullptr en C++11)

    Au final, cela pourrait ressembler à quelque chose comme
    ClassA.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class ClassB;
    class ClassA{
        public:
            ClassA(ClassB* b):b_(b){}
            ~ClassA(){/* surtout pas de delete b_ ici */}
            /*...*/
        private:
            B* b_;
    };
    classB.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class ClassB{
        /* ce qui va bien */
    };
    main.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <ClassA.h>
    #include <ClassB.h>
    int main(){
        ClassB * myB = new ClassB(/* ...*/);
        ClassA firstA(myB);
        ClassA secondA(myB);
        /* ... */
        delete myB;
        return 0;
    } // firstA et secondA étant détruits automatiquement, il n'y aura pas de problème, mais d'autres
      // situations peuvent être plus complexes ;)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 188
    Points : 51
    Points
    51
    Par défaut
    Merci pour la réponse.


    Mais est ce qu'on peut faire autrement dans main.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    B b1(/****/); 
    A a1(&b1);
    A a2(&b1);
    :

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 113
    Points : 32 958
    Points
    32 958
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par kochfet Voir le message
    Merci pour la réponse.


    Mais est ce qu'on peut faire autrement dans main.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    B b1(/****/); 
    A a1(&b1);
    A a2(&b1);
    :
    Que voudrais-tu faire autrement ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Que voudrais-tu faire autrement ?
    recourir à l'allocation dynamique de la mémoire pour b1

    Oui, effectivement, tu peux parfaitement te contenter de "prendre l'adresse" d'une variable déclarée sur la pile.

    Mais bon, il faut savoir que, si tu déclares des instances de type ClassA (selon mon exemple) en leur fournissant une adresse qui correspond à un objet créé sur la pile, cette adresse sera invalidée au moment de la destruction de l'objet, et donc au moment où tu sortiras de la portée dans laquelle l'objet a été déclaré.

    Cela peut poser problème dans certaines situations
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 113
    Points : 32 958
    Points
    32 958
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par koala01 Voir le message
    recourir à l'allocation dynamique de la mémoire pour b1
    Faut comprendre et c'est pas évident, parce que ton exemple plus haut c'est déjà ce qu'il fait.
    Allocation dynamique ou pas, tant qu'on retrouve un pointeur c'est du pareil au même. Il faut juste "faire attention" à la durée de vie de l'objet pointé.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 851
    Points : 2 293
    Points
    2 293
    Par défaut
    J'aurais pensé à une méthode publique private getInstance() qui retournerait le pointeur. Un truc comme ça :

    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
    class A
    {
    public:
      static A* getInstance()
      {
         if (!m_instance)
           m_instance = new A;
         return m_instance;
      }
      virtual ~A();
     
    private:
      A();
      static A* m_instance;
    };

  8. #8
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Points : 718
    Points
    718
    Par défaut
    Hello,

    Je pense que les shared_ptr seraient une bonne idée dans ce cas là non?

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 113
    Points : 32 958
    Points
    32 958
    Billets dans le blog
    4
    Par défaut
    Ce que tu présentes là ressemble de loin à un singleton.
    Mais il n'y a besoin d'aucun artifice de ce genre pour récupérer une instance.
    this est l'instance en cours.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  10. #10
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 188
    Points : 51
    Points
    51
    Par défaut
    Le passage par pointeurs est la solution que je l'ai trouvée.

    Merci à tous.

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

Discussions similaires

  1. Comment ecrire sur la meme ligne avec la commane ECHO
    Par juflata dans le forum Windows
    Réponses: 3
    Dernier message: 24/11/2015, 10h06
  2. Réponses: 2
    Dernier message: 25/08/2011, 18h43
  3. [6.5] Comment pointer sur un autre univers ?
    Par Orsombre dans le forum Webi
    Réponses: 2
    Dernier message: 17/09/2008, 15h42
  4. [XPath/VB.Net] Comment pointer sur un noeud enfant ?
    Par Petit_ange dans le forum Accès aux données
    Réponses: 5
    Dernier message: 27/08/2006, 14h15
  5. Différentes instances de XMLRAD sur le meme serveur
    Par mchicoix dans le forum XMLRAD
    Réponses: 5
    Dernier message: 09/08/2005, 16h42

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