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 :

[POO] UML Association en C++ et les pointeurs


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 23
    Points : 16
    Points
    16
    Par défaut [POO] UML Association en C++ et les pointeurs
    Bonjour,


    Quel est la meilleure façon d'avertir l'objet c2 de la disparition de c1 ?
    Ci-joint un exemple ?

    Merci

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    class C1
    {
      public:
        C1(void) : _objectNumber(_objectCount++) {}
        ~C1(void) { --_objectCount; }
      public:
        std::size_t objectNumber(void) { return _objectNumber; }
      private:
        static std::size_t _objectCount;
        std::size_t _objectNumber;
    };
     
    std::size_t C1::_objectCount = 0;
     
    class C2
    {
      public:
        C2(C1* c1) : _objectNumber(_objectCount++) { _c1 = c1; }
        ~C2(void) { --_objectCount; }
      public:
        std::size_t test(void) { return _c1->objectNumber(); }
        bool isValid(void) { return _c1!=NULL; }
      private:
        static std::size_t _objectCount;
        std::size_t _objectNumber;
        C1* _c1;
    };
     
    std::size_t C2::_objectCount = 0;
     
    int main(int argc, char* argv[], char* argenv[])
    {
      C1* c1 = new C1();
      C2 c2(c1);
      std::cout<<c2.isValid()<<std::endl;
      std::cout<<c2.test()<<std::endl;
      delete c1;
      c1 = NULL;
      std::cout<<c2.isValid()<<std::endl;
      std::cout<<c2.test()<<std::endl;
      return EXIT_SUCCESS;
    }
    Résultat :
    1
    0
    1
    0

  2. #2
    Membre expert
    Avatar de hiko-seijuro
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 011
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 011
    Points : 3 065
    Points
    3 065
    Par défaut
    je vais peut etre dire une anerie mais tu as regardé des pointeurs intelligents ?
    Hiko-seijuro

    n'cha - hoyoyo gang

    espace perso : http://hiko-seijuro.developpez.com
    dernier tuto : Introduction à l'éditeur de texte Emacs sous linux
    consulter les faqs : http://www.developpez.com/faq
    PAS DE QUESTIONS TECHNIQUES PAR MP OU MAIL

  3. #3
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Attention ici tu n'as pas écrit de constructeur par recopie !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class C1
    {
      public:
        C1(void) : _objectNumber(_objectCount++) {}
        C1(const C1& c1)  { _objectNumber = _objectCount++ ;}
        ~C1(void) { --_objectCount; }
      public:
        std::size_t objectNumber(void) { return _objectNumber; }
      private:
        static std::size_t _objectCount;
        std::size_t _objectNumber;
    };

  4. #4
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par hiko-seijuro Voir le message
    je vais peut etre dire une anerie mais tu as regardé des pointeurs intelligents ?
    Oui boost::shared_ptr stocke un compteur de référence.
    Un pattern observateur fera aussi l'affaire. La destruction d'un objet observé tient au courant une liste d'observateur...

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 23
    Points : 16
    Points
    16
    Par défaut
    Effectivement il existe un bug car le constructeur par recopie n'est pas implémenté...

    J'aimerai trouver une façon de faire sans utiliser les shared_ptr ou les ????_ptr.

    Avez vous une implémentation C++ du pattern observateur ?

    thx

  6. #6
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Oui j'imagine que tu voudrais réassigner des numéros pour chaque instance après destruction d'un objet pour pas avoir plusieurs fois le même numéro...

    Le pattern observateur sera je pense, très bon.
    http://come-david.developpez.com/tut...ge=Observateur

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Pour faire un pattern observateur, voir aussi boost::signal. C'est un peu plus sur qu'un vague code d'exemple bourré de pointeurs

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 23
    Points : 16
    Points
    16
    Par défaut
    Je n'ai pas trop envie d'utiliser boost, surtout qu'à l'époque le portage MinGW me paraissait pas très sérieux... reste à voir maintenant...
    Je souhaiterai trouver un moyen simple et élégant pour que l'objet c2 se rende compte que c1 a était détruit sans modifier la cinématique du code du main...

  9. #9
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    C'est pas simplement un weak_ptr que tu veux ?
    Boost ftw

  10. #10
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    Citation Envoyé par kris1980 Voir le message
    Je n'ai pas trop envie d'utiliser boost, surtout qu'à l'époque le portage MinGW me paraissait pas très sérieux... reste à voir maintenant...
    Je souhaiterai trouver un moyen simple et élégant pour que l'objet c2 se rende compte que c1 a était détruit sans modifier la cinématique du code du main...
    J'ai utilisé assez récemment MinGW avec Boost.Signal et Boost.SmartPtr pour un projet pro. Aucun problème à signaler, tu peux y aller les yeux fermés, à mon avis.

    Autrement, les smart_ptr me semblent bien plus adaptés à ton problème.

    Si tu ne veux vraiment pas utiliser Boost, les smart_ptr sont dans std::tr1.
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  11. #11
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par zais_ethael Voir le message
    Pour faire un pattern observateur, voir aussi boost::signal. C'est un peu plus sur qu'un vague code d'exemple bourré de pointeurs
    Oui c'est vrai. Mais bon on trouve d'excellents livres sur le sujet. Ou bien sur Google également.

    Pour le posteur :
    Le principe est assez simple, tu as deux classes de bases Observable et Observateur qui sont là pour découpler ton système. Observable possède une liste d'observateur et sait que chaque Observateur implémente une méthode Update().
    Ainsi pour chaque modif (ici ton destructeur en fait), il faut parcourir la liste d'Observateur et appeler la méthode Update().

    SI j'ai un peu de temps cette semaine, j'essaierai de détailler un peu plus...

    EDIT : +1 pour Boost tout de même.

  12. #12
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Juste une dernière note pour boost et Mingw: les binaires sont rares, mais on en trouve de très bien dans la distro de nuwen.

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 23
    Points : 16
    Points
    16
    Par défaut
    Hello, comme l'indique Matthieu Brucher dans son article :
    http://matthieu-brucher.developpez.c...ost/smartptrs/

    Le but de ces pointeurs est simple : ne plus s'occuper de l'effacement au bon moment de la mémoire allouée dynamiquement. C'est une espèce de garbage collector. Dès que le pointeur est effacé, la mémoire associée peut être désallouée si plus personne n'y fait référence.
    Dans mon cas la classe C2 utilise C1 (association unidirectionnelle C1 ne connait pas C2), C2 doit être averti que C1 est détruit. Je ne souhaite pas que C1 continue à fonctionner mais je souhaite qu'il détecte la rupture du lien...

    Je pense m'orienter vers le pattern observer... Me tromperais-je ?

  14. #14
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Pour ma part, je partirai
    • Soit sur boost.Signals
    • Soir un pattern Observer


    Le pattern Observer ne sera vraiment pas long à mettre en place (30 min max), et c'est relativement efficace.
    boost.Signals est une implémentation du pattern Observer, donc ça peut valoir le coup de s'y mettre...
    Perso je partirai plus sur un pattern Observer si j'ai juste ça à faire. Dans un cas plus compliqué, boost sera parfait.

    A toi de voir.

    Poukill.

  15. #15
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    Pourquoi écrire soit-même un observer si c'est déjà implémenté dans une lib ? C'est pas un peu réinventer la roue ?
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  16. #16
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par Florian Goo Voir le message
    Pourquoi écrire soit-même un observer si c'est déjà implémenté dans une lib ? C'est pas un peu réinventer la roue ?
    Pour comprendre le pattern... Ca va assez vite et c'est très formateur

    Sinon je suis d'accord avec toi évidemment.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    Citation Envoyé par Florian Goo Voir le message
    Pourquoi écrire soit-même un observer si c'est déjà implémenté dans une lib ? C'est pas un peu réinventer la roue ?
    Dans l'absolu, je suis tout à fait d'accord avec le principe de ne pas (mal) faire quelque chose dont on sait pertinemment qu'une bibliothèque fait sans doute beaucoup mieux que toi...

    Cependant, il y a quelques - rares - cas dans lesquels ce principe n'est pas *forcément* applicable: lorsque la méconnaissance de la bibliothèque en question va de paire avec l'absence de la dite bibliothèque sur l'ordinateur de dev, et qu'il s'agit d'implémenter un (nombre restreint de) pattern(s) clairement reconnu(s) et compris.

    En effet, il ne faut pas plus de 5 à 10 minutes, lorsque l'on connait le pattern observateur (à peine plus s'il faut se baser sur une doc quelconque) pour en fournir une implémentation adaptée à nos besoins, alors que s'il faut commencer par la télécharger (dieu merci, l'époque du 56k est révolue !!!), la compiler, avant de pouvoir envisager de se perdre dans l'ensemble des classes et des fonctions qu'elle présente afin d'arriver à déterminer quelle syntaxe a été attendue par le créateur de la bibliothèque, le facteur temps peut prendre une grande importance.

    En outre, comme l'a si bien dit poukill, l'implémentation personnelle est vachement enrichissante (surtout lorsqu'il s'agit d'un desing pattern) du point de vue didactique.

    Si enfin, la personne qui doit implémenter ce desing pattern a des réticences - à tord ou à raison - quant à l'utilisation d'une bibliothèque particulière, toutes les raisons de l'implémenter personnellement sont réunies
    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

  18. #18
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    Bien vu, j'avais pas pensé à ça
    C'est vrai que quand j'ai commencé à étudier les patterns et à écrire mon propre observer, j'ai compris d'un coup tout un tas de trucs sur la gestion d'évènements dans les libs d'interface graphique !
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  19. #19
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Citation Envoyé par poukill Voir le message
    Pour ma part, je partirai
    • Soit sur boost.Signals
    • Soir un pattern Observer
    J'ai une big objection sur cette remarque. Non, sans rire, sous entendre qu'il puisse y avoir une distinction entre le pattern Observer et boost.signals relève de l'hérésie. Pour vulgariser, ce pattern ne fait jamais qu'expliquer la réalisation d'un système d'évènements, et boost.signals est très exactement fait pour simplifier la réalisation de ce genre de système. Le look "fonctionnel" (utilisation de foncteurs, simple facilité syntaxique du langage) de cette biblio n'affecte en rien son potentiel.

    En sachant cela ça se résume, à mon sens, à inclure ou pas une biblio externe. (Je ne suis pas d'accord avec toi koala, taper du code uniquement pour s'entrainer sur un concept théorique est une chose, mais utiliser ce code dans un programme en est une autre - quand bien même ce serait un exercice à rendre au prof).

  20. #20
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Un pattern est un pattern, c'est à dire un modèle de conception. Donc quelque chose d'abstrait.
    boost.Signals est une implémentation du pattern Observer, rudement bien écrite, certes, mais ne va pas éclairer un débutant sur la vrai façon de programmer un design pattern observer.
    Observer et comprendre fondamentalement un pattern, c'est autre chose que faire un #include <boost/signals> et faire un copier coller d'un tutorial... Quand on a vraiment compris quelque chose, c'est pour longtemps. Appliquer une solution à un problème que l'on a pas pris le temps de comprendre, c'est se reposer les mêmes questions 6 mois après quand le même problème se posera...
    Pédagogiquement, je suis "pour" comprendre en faisant.

    Après, une fois de plus, quand le pattern est bien compris (d'après les posts du demandeur ici présent ce n'est pas le cas), je suggère comme Koala d'utiliser les libs qui "marchent". Et boost en fait parti...

Discussions similaires

  1. [LG]Les pointeurs: Forme en "Anneaux"
    Par k o D dans le forum Langage
    Réponses: 4
    Dernier message: 20/10/2004, 07h29
  2. Réponses: 4
    Dernier message: 13/08/2004, 18h39
  3. [TTreeView] Problème avec les pointeurs d'objet
    Par BlackWood dans le forum Composants VCL
    Réponses: 2
    Dernier message: 02/07/2004, 14h31
  4. pointeurs, toujours les pointeurs :/
    Par giviz dans le forum C
    Réponses: 16
    Dernier message: 08/10/2003, 15h02
  5. Pb de débutant sur les pointeurs!!!
    Par benji17c dans le forum C
    Réponses: 6
    Dernier message: 30/09/2003, 17h50

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