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

MFC Discussion :

[MFC] Retourner une liste d'objets


Sujet :

MFC

  1. #1
    Nouveau membre du Club

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 14
    Points : 33
    Points
    33
    Par défaut [RESOLU][MFC] Retourner une liste d'objets
    Bonjour à tous,


    J'essaie sans succés de retourner une liste d'objet [CPtrList] entre plusieurs classes :

    La classe A détient la liste : CPtrList listeA;.

    La classe B fait un : CPtrList* listeB = A.getListeA();

    La classe C fait un CPtrList* listeC = B.getListeB();

    La liste de A est initialisée correctement, il y a plusieurs valeurs dedans.

    Dans B, je récupére bien la première liste (A) et je vois les données.

    Par contre, dans C, rien du tout ! La liste est vide ! B.getListeB(); retourne pourtant un CPtrList* qui provient de A.

    J'ai également essayé de passer des CPtrList mais il n'y a pas d'opérateur d'affectation entre deux listes CPtrList (i.e. CPtrList B = CPtrList A est impossible).


    Vous avez une idée d'où peut provenir le problème ?


    Merci,

    G.

  2. #2
    Membre régulier

    Inscrit en
    Décembre 2002
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 60
    Points : 105
    Points
    105
    Par défaut
    Ce serait bien d'avoir quelques echantillons de code. Comment passes-tu exactement la liste de A vers B, puis de B vers C.

    Savoir que tu utilises une fonction nommee getListB n'est pas de beaucoup d'aide si on ne sait pas ce qu'elle contient, et comment elle est utilisee.
    Si la connaissance peut créer des problemes, ce n'est pas par l'ignorance que l'on peut les résoudre.
    -- Isaac Asimov

  3. #3
    Nouveau membre du Club

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 14
    Points : 33
    Points
    33
    Par défaut
    Je vous mets le code ci-dessous.


    La classe A détient la liste : CPtrList listeA;.

    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
    {
    private:
    CPtrList listeA;
     
    public:
    CPtrList* getListeA();
    }
     
    CPtrList* A::getListeA()
    {
    return &listeA; // retourne l'adresse de A 
    // Fonctionne : la classe B récupére et accéde bien aux éléments de A sans problème
    }
    La classe B fait un : CPtrList* listeB = A.getListeA();
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class B
    {
    public:
    CPtrList* getListe();
    }
     
    CPtrList* B::getListe()
    {
    A maClasseA;
     
    return maClasseA.getListeA(); // retourne le pointeur B (qui pointe vers A)
    }
    La classe C fait un CPtrList* listeC = B.getListe();
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CPtrList* listeC = maClasseB.getListe();

    Pour résumé :

    CPtrList* listeC = maClasseB.getListe();
    correspond à :
    CPtrList* listeC == & maClasseA.getListeA(); // Adresse de la liste A


    Le problème est que listeC ne contient rien !

    Par contre, si je fais directement : CPtrList* listeC = &maClasseA.getListeA() alors listeC pointe bien vers les éléments de A.

    On dirait que le problème vient de l'affectation entre B et C quand je fais : listeC = maClasseB.getListe().

    Est-ce un problème de faire un CPtrList* = CPtrList* (copie de pointeur) :

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 9
    Points : 7
    Points
    7
    Par défaut
    l'operateur d'affectation est remplacé par un semblant de constructeur par recopie addTail ou addHead qui peuvent prendre en parametre un CObjList

  5. #5
    Nouveau membre du Club

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 14
    Points : 33
    Points
    33
    Par défaut
    je teste de suite... (suspense)

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 9
    Points : 7
    Points
    7
    Par défaut
    j'ai l'impression que dans ta methode getListe de ta classe B tu creer un objet de ta classe A dans la pile (pas d'utilisation de new) donc celui-ci est detruit a la fin de l'execution de ta methode et donc ton pointeur pointe sur rien

  7. #7
    Membre régulier

    Inscrit en
    Décembre 2002
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 60
    Points : 105
    Points
    105
    Par défaut
    Est-ce que getListeB retourne vraiment un pointeur sur une liste d'un objet A cree localement a la fonction comme dans ton exemple de code?

    Si c'est le cas, alors comme l'instance de A contenant la liste n'est plus valable a la sortie de la fonction, c'est normal que C ne puisse pas acceder aux elements.

    Ton echantillon est ou bien faux ou bien incomplet. Tu ne montre pas ListeB comme etant une variable membre de la classe B.

    return maClasseA.getListeA(); // retourne le pointeur B (qui pointe vers A)
    Ca retourne un pointeur qui pointe vers la liste de "maClasseA", pas de A. Il ne faut pas confondre classe et objet.

    Sinon, ton code me parait extremement dangereux. Faire pointer comme ca plusieurs objets sur l'adresse d'un membre prive d'un autre objet est pour le moins une pratique inhabituelle, et a de fortes chances de planter si l'objet de type A est detruit avant les objets de type B et C.

    Il serait preferable d'avoir des pointeurs partout (y compris dans A). Mieux encore, il serait preferable d'avoir des "smart pointers". Ca te permet de t'assurer que la memoire ne sera liberee que quand plus rien ne pointera dessus.
    Si la connaissance peut créer des problemes, ce n'est pas par l'ignorance que l'on peut les résoudre.
    -- Isaac Asimov

  8. #8
    Nouveau membre du Club

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 14
    Points : 33
    Points
    33
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Est-ce que getListeB retourne vraiment un pointeur sur une liste d'un objet A cree localement a la fonction comme dans ton exemple de code?
    Oui, et j'ai des doutes par rapport à ce que vous avez dit sur la durée de vie du pointeur émanant de B.


    Pour moi, quand je fais un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CPtrList* B::getListe()
    {
    A maClasseA;
     
    return maClasseA.getListeA(); // retourne le pointeur B (qui pointe vers A)
    }
    Cela devrait renvoyer l'adresse de la liste A.

    Ainsi la classe C qui reçoit cette adresse peut aller consulter les données de la liste A.

    Apparement je n'avais pas compris cela.


    Avez-vous une idée pour résoudre mon problème. Je suis dans une architecture IHM - Controleur - Métier. Comme vous l'avez deviné la classe A fait partie du métier, B est le contoleur et C l'IHM.

    Pour faire pratique, un exemple :

    l'IHM Client demande au contoleur de lui donner la liste des produits pour le client numéro 22. Cela donne en code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ControlClient* ccli = new ...;
    CptrList* listeProduits = ccli.getListeProduits( numeroClient ); //numeroClient = 22
    Le controleur demande au client ayant le numéro 22 de donner sa liste de produits.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Client c22; // on suppose que l'on récupére le client n°22 comme cela ;-)
     
    return c22.getListeProduits();
    Le client (classe métier) renvoit sa liste (membre privé)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return &listeProduits; // l'adresse de sa liste
    NB: la liste de produits du client est une CPtrList initialisée avec des pointeurs sur des objets alloués avec new(...)

  9. #9
    Nouveau membre du Club

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 14
    Points : 33
    Points
    33
    Par défaut
    Conclusion :

    Mon problème est que le controleur ne devrait être qu'un transmetteur entre l'IHM et le Métier (c'est son rôle).

    Mais je n'y arrive pas aussi facilement que cela !

    Vous avez des idées pour transmettre ma liste provenant de A vers C :


    En tout cas, merci pour vos précédentes réponses.

  10. #10
    Membre régulier

    Inscrit en
    Décembre 2002
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 60
    Points : 105
    Points
    105
    Par défaut
    Deux ou trois options:
    - T'arranger pour que l'objet correspondant au client 22 ait une duree de vie au moins egale a la duree d'utilisation de la liste (apparemement pas facile vu ton architecture).
    - Faire de la variable membre de A un pointeur. Tu fais un new dans le constructeur et pas de delete dans le destructeur, et facon a ce que la liste existe toujours une fois l'objet creer. Il faut faire attention a ce que le client detruise la liste (delete) une fois qu'il a fini de l'utiliser (solution sale, dangereuse, avec des fuites de memoire presque assuree).
    - Faire une copie de la liste: ecrire toi-meme le code necessaire a la copie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    bool B::getListeB(int nClient, CListPtr* listeC)
    {
      if (!listeC) return false;
      A client(nClient);
      CListPtr* listeB = client.GetListA();
      for &#40;int i = 0; i < listeB->GetSize&#40;&#41;; ++i&#41;
        listeC->Add&#40;&#40;*listeB&#41;&#91;i&#93;&#41;;
      return true;
    &#125;
    - Revoir l'architecture de ton programme et les relations entre les classes.
    Si la connaissance peut créer des problemes, ce n'est pas par l'ignorance que l'on peut les résoudre.
    -- Isaac Asimov

  11. #11
    Nouveau membre du Club

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 14
    Points : 33
    Points
    33
    Par défaut
    Citation Envoyé par Elrond
    Deux ou trois options:
    - T'arranger pour que l'objet correspondant au client 22 ait une duree de vie au moins egale a la duree d'utilisation de la liste (apparemement pas facile vu ton architecture).
    Je ne vois même pas comment faire dans le code ! ;-/


    Citation Envoyé par Elrond
    - Faire de la variable membre de A un pointeur. Tu fais un new dans le constructeur et pas de delete dans le destructeur, et facon a ce que la liste existe toujours une fois l'objet creer. Il faut faire attention a ce que le client detruise la liste (delete) une fois qu'il a fini de l'utiliser (solution sale, dangereuse, avec des fuites de memoire presque assuree).
    Je viens de la faire et j'ai eu ça dans mes TRACE :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    C&#58;&#58; -572662307 éléments dans la liste
    Detected memory leaks!
    Dumping objects ->...
    -572662307 ça fait quand même beaucoup d'éléments ;-)

    Je me suis rendu compte en placant des TRACE dans les destructeur de la durée de vie de ma listeA. En effet, la liste est aussitôt supprimée avec A, ce qui tout à fait normal mais c'est sur quoi je buttais depuis ce matin ! Grrr.

    Citation Envoyé par Elrond
    - Faire une copie de la liste: ecrire toi-meme le code necessaire a la copie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    bool B&#58;&#58;getListeB&#40;int nClient, CListPtr* listeC&#41;
    &#123;
      if &#40;!listeC&#41; return false;
      A client&#40;nClient&#41;;
      CListPtr* listeB = client.GetListA&#40;&#41;;
      for &#40;int i = 0; i < listeB->GetSize&#40;&#41;; ++i&#41;
        listeC->Add&#40;&#40;*listeB&#41;&#91;i&#93;&#41;;
      return true;
    &#125;
    - Revoir l'architecture de ton programme et les relations entre les classes.
    Vraiment intéressant ce petit bout de code ! Je vais tester de suite. En plus ça cadre complétement avec le boulot qu'est censé faire le Contôleur : donner une liste à l'IHM mais une NOUVELLE liste, pas celle de A qui est détruite !

    Elle est pas belle la vie ? 8)


    Merci Elrond d'avoir passé du temps ! J'ai failli me suicider à coup de google et de MSDN !

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

Discussions similaires

  1. [WS][ArrayList]Retourner une liste d'objet
    Par mezoo dans le forum Services Web
    Réponses: 2
    Dernier message: 25/01/2010, 17h04
  2. methode serveur qui retourne une liste d'objet
    Par harbi dans le forum Windows Communication Foundation
    Réponses: 1
    Dernier message: 01/12/2008, 10h11
  3. methode qui retourne une liste d'objets du meme type
    Par anoukhan dans le forum Oracle
    Réponses: 8
    Dernier message: 12/01/2006, 19h38
  4. [MFC] creer une liste avec des check????
    Par ginounet dans le forum MFC
    Réponses: 4
    Dernier message: 16/06/2004, 12h47
  5. (MFC) Redimensionner une List Control auto / Boite Dlg
    Par Guybrush113 dans le forum MFC
    Réponses: 7
    Dernier message: 23/04/2004, 10h24

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