Partage
  • Partager sur Facebook
  • Partager sur Twitter

passage de pointeur

Sujet résolu
    13 juin 2018 à 17:31:39

    bonjour,

    je suis sur un projet personnel qui nécessite un arbre.

    je n'arrive pas à récupérer les nœuds que j'y insère.

    #include"TreeEvent.h"
    
    int main(int argc, char**argv)
    {
            TreeEvent *tree = new TreeEvent();
            Goblin sprite;
            tree->addNode(&sprite);
            Node* node = tree->find(&sprite);
    		delete tree;
            return EXIT_SUCCESS;
    }

    et ma classe TreeEvent où la classe Goblin n'est là qu'en tant que test en attendant la véritable.

    #ifndef TREEEVENT_H
    #define TREEEVENT_H
    
    #include<stdlib.h>
    
    class Goblin{
            public:
                    Goblin()
                    {
                            static int v = 0;
                            v++;
                            value=v;
                    }
                    int value;
    };
    typedef struct Node_{
            Goblin* item;
            Node_* parent;
            Node_** children;
            int size;
            int length;
            Node_(Goblin* item, Node_*parent):item(item), parent(parent), size(0), length(5)
            {
                    children = (Node_**)malloc(length * sizeof(Node_*));
            }
    		~Node_(){}
    } Node;
    
    class TreeEvent{
            public:
                    TreeEvent(){
                            root = new Node(nullptr, nullptr);
                    }
            
                    int addNode(Goblin* item, Node** parent = nullptr)
                    {
                            if(parent == nullptr)
                            {
                                   nodeRealloc(&root); 
                                   root->children[root->size - 1] = new Node(item, root);
    							   return 0;
                            }else{
                                   nodeRealloc(parent); 
                                   (*parent)->children[(*parent)->size - 1] = new Node(item, *parent);
    							   return 0;
                            }
    						return -1;
                    }
    
                    void remNode(Node** node = nullptr)
                    {
                            if(node == nullptr)
                                    *node = root;
                            for(int i = 0; i < (*node)->size; i++)
                            {
                                    if((*node)->children[i]->size)
                                            remNode(&(*node)->children[i]);
                                    
                                    delete (*node)->children[i]; 
                            }
    						delete[] (*node)->children;
                    }
    
                    Node* find(Goblin* item, Node* node = nullptr)
                    {
    						if(node != nullptr && node->item == item)
    								return node;
                            if(node == nullptr)
                                    node = root;
                            for(int i = 0; i < node->size; i++)
                            {
    							find(item, node->children[i]);
                            }
                    }
    
                    ~TreeEvent()
                    {
                            remNode();
                            delete root;
                    }
                            Node* root;
                    
                    private:
                            void nodeRealloc(Node** node)
                            {
                                    (*node)->size++;
                                    if((*node)->size == (*node)->length)
                                    {
                                            (*node)->children = (Node**)realloc((*node)->children, (*node)->length * 2 *sizeof(Node*));
                                            (*node)->length *= 2;
                                    }
                            }
    };
    
    #endif
    


    au retour de la fonction "find" le pointeur Node* node est null.

    sur ce coup là... HELP!!

    PS: j'avais oublié le return dans l'appel récursif à find. Fausse alerte, c'était pourtant simple.

    -
    Edité par amaurybenard 13 juin 2018 à 17:45:01

    • Partager sur Facebook
    • Partager sur Twitter
      13 juin 2018 à 17:58:52

      Salut,

      Plusieurs choses :

      - TreeEvent, alors que c'est visiblement un arbre, ca ne me semble pas vraiment opportun : Les identifiants que tu donnes (à tes classes, à tes structures, à tes types personnalisés, de manière générale, à tes données et à tes fonctions) devraient systématiquement respecter une règle toute simple : leur nom doit permettre au lecteur du code (quel qu'il soit, et qui peut être toi, dans un mois ou dans un an) de se faire une idée très claire de l'usage auquel tu le destine.

      Dans le cas présent, TreeEvent (que j'aurais personnellement plutot appelé EventTree, mais passons) donne l'impression que tu vas y placer... des Events (des événements).

      Or, il contient -- de toute évidence -- ... des Goblins...  Cherchez l'erreur :D

      - Tu n'as absolument aucun besoin d'avoir recours à l'allocation dynamique de la mémoire por créer ta donnée tree.  Et surtout pas à "l'ancienne" : lorsque tu as recours à l'allocation dynamique de la mémoire, tu devrais utiliser les pointeurs intelligents

      - Les collections -- de manière générale -- s'accommodent très mal de la notion d'héritage, surtout lorsque c'est pour créer susceptible d'être lui-même utilisé en tant que collection.

      De plus, ce n'est pas parce que deux collections différentes proposent les mêmes services (ajout, suppression, parcours et recherche d'éléments) qu'il est possible de les utiliser en ayant recours à la substituabilité : le type des éléments qu'elles doivent maintenir s'y opposera le plus souvent.

      - Il existe deux grands types de collections : les collections qui sont propriétaires des éléments qu'elles contiennent et celles qui n'en sont que les utilisateurs.

      Les premières ont droit "de vie et de mort" sur les éléments qu'elles contiennent (comprend: elles peuvent décider de détruire l'un des éléments qu'elle contienntent à n'importe quel moment) alors que les deuxième n'en ont absolument pas le droit : elle ne peuvent que les utiliser.

      On préférera généralement utiliser des pointeurs (intelligents, cela va de soi)  pour les premières et des wrapper de référence pour les deuxièmes, afin de faire clairement la distinction entre les deux ;)

      - malloc, c'est du C, l'allocation dynamique de la mémoire en C++ se fait à l'aide de new (enfin, quand elle se fait à "l'ancienne mode")

      - Ta structure Node provoque une fuite mémoire

      - La bibliothèque standard fourni un tas de collections particulièrement sympa:  std::vector (un tableau d'éléments) ou std::array (quand le nombre d'élément est connu à la compilation), std::tree (un arbre binaire), std::map (une association clé -> valeur triée sur base de la clé, avec recherche dichotomique).

      Uses en et abuses en, cela te facilitera énormément la vie ;)

      • Partager sur Facebook
      • Partager sur Twitter
      Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
        14 juin 2018 à 0:17:34

        salut koala01 ,

        j'ai compris que je devais utiliser les collections.

        Et dans mon nouveau topic retour de fonction , j'ai utilisé les std::vector.

        Je n'ai pas compris la différence entre collection propriétaire et collection utilisatrice... Un petit lien serait le bienvenu.

        Ensuite, un arbre depuis lequel on peut accéder au parent de chaque nœud ne peut être autre chose qu'un arbre de propagation d'évènement à mon sens.

        D'où le nom de TreeEvent.

        Ou EventTree c'est comme tu voudras. Mais ce n'est pas le propos.

        S'il te plaît, rends-toi sur mon nouveau topic et discutons en.

        à+

        • Partager sur Facebook
        • Partager sur Twitter
          14 juin 2018 à 15:21:57

          amaurybenard a écrit:

          salut koala01 ,

          j'ai compris que je devais utiliser les collections.

          Et dans mon nouveau topic retour de fonction , j'ai utilisé les std::vector.

          Je n'ai pas compris la différence entre collection propriétaire et collection utilisatrice... Un petit lien serait le bienvenu.

          A vrai dire, ce n'est pas spécifique aux collections. C'est vrai pour n'importe quel "agrégat" de données ainsi que pour n'importe quel comportement (faisons simple: les fonctions)

          De manière générale, dés que "quelque chose" manipule des données, tu dois te poser des questions comme:

          • d'où viennent les données manipulées ?
          • Est-ce qu'il est cohérent que l'élément qui manipule ces données décide d'en créer un "nouveau jeu de données" pour elle-même?
          • Est-ce qu'il est cohérent que l'élément qui manipule ces données décide de  détruire les données qui n'ont pas été créées par elles?
          • Est-ce qu'il est cohérent que l'élément qui manipule ces données décide de détruire celles qu'elle a elle-même créées?

          amaurybenard a écrit:

          salut koala01 ,

          Ensuite, un arbre depuis lequel on peut accéder au parent de chaque nœud ne peut être autre chose qu'un arbre de propagation d'évènement à mon sens.

          Et tu te trompes très lourdement : un arbre qui permet d'accéder au parent des noeuds qu'il contient pourra être utilisé dans une quantité invraissemblable de situations diverses et variées!

          En outre, si tu veux -- effectivement -- créer un arbre de propagation d'événements, ce qu'il doit contenir, ce sont ... des événements, et non de quelconque ... Goblins (ou elfes ou charettes ;) ), parce qu'un Goblin, un Elfe ou une Charette... Ce ne sont pas des événements!

          Au mieux, on peut considérer que Goblins, Elfes et Charette sont susceptibles d'émettre certains événements qui pourront être pris en charge par un EventTree.

          Mais, dans ce cas, ce sont les Goblins, les Elfes et autres Charettes qui créent l'événement, puis qui le transmettent à ton EventTree.  Et ton EventTree prendra la responsabilité "pleine et entière" de touts les événements qu'on lui aura transmis;  y compris celle de les détruire correctement lorsqu'ils ne seront plus nécessaires  (il deviendra le "propriétaire légitime" de ces événements ;) )

          -
          Edité par koala01 14 juin 2018 à 15:33:43

          • Partager sur Facebook
          • Partager sur Twitter
          Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
            14 juin 2018 à 18:10:59

            Merci pour la précision sur les collections koala01.

            Je suis d'accord avec toi. Mon arbre peut avoir diverses fonctions.

            Je me contenterai donc de l'appeler disons: DoubleLinkedTree.

            En suite, le fait qu'il manipule des Goblins n'est pas provisoire ( en l'état actuel de ma réflexion ).

            Mon idée était que chaque sprite, que j'ai nommé ici Goblin, aurait une fonction addChild style AS3 afin d'ajouter un nœud à l'arbre, ce dernier étant traité dans mes évènements.

            Ensuite je peux éventuellement utiliser les templates pour plus de polyvalence.

            Suis-je parti du bon pied?

            S'il te plaît, rends toi sur le topic sus-mentionné.

            J'en ai créé un nouveau, je n'aurais pas dû, mais c'est fait.

            Il s'agit de la même histoire.

            • Partager sur Facebook
            • Partager sur Twitter
              14 juin 2018 à 18:31:52

              Que tu aies une, dix ou 150 calsses susceptibles d'émettre des événement n'est pas le problème.  Le problème, c'est le sens, la "définition" que tu donne (comme un dictionnaire) à  tes classes.

              Pour moi, il n'y a rien à faire: un goblin n'est pas un événement.  Point- barre.

              Un goblin peut émettre un événment. Un événement peut être "rattaché" au goblin qui l'a émis (cela peut s'avérer utilie/ nécessaire / indispensable dans certaines situations).  Mais un goblin n'est pas plus un événement qu'un événement ne peut être considéré comme étant un goblin!

              Ce sont donc deux notions totalement différentes et indépendantes, qui doivent être représentées dans ton code par des types de données différents.

              Tu veux créer un arbre d'événement? libre à toi.  Mais cet arbre d'événment doit contenir... des événement.  Il n'a rien à faire d'un quelconque goblin ;)

              • Partager sur Facebook
              • Partager sur Twitter
              Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                14 juin 2018 à 19:16:06

                C'est justement pour l'émission et la réception d'événements depuis mes objets que je crée un arbre qui manipule ces mêmes objets ( ici goblins ) sous forme de template.

                Ce dont tu me parles est une question de sémantique.

                Et j'y ai déjà répondu en te disant que je renommerai mon arbre.

                Mon arbre ne contiendra pas des événements mais les objets qui s'y rattachent, la propagation des événements ne se faisant que d'objets contenus à objets contenant.

                • Partager sur Facebook
                • Partager sur Twitter
                  15 juin 2018 à 4:07:20

                  amaurybenard a écrit:

                  C'est justement pour l'émission et la réception d'événements depuis mes objets que je crée un arbre qui manipule ces mêmes objets ( ici goblins ) sous forme de template.

                  Mais, justement! Ton arbre, il a déjà bien assez à faire en devant s'occuper de gérer les différents événements qu'on lui donne pour que l'on n'aille pas, en plus, lui imposer la responsabilité de manipuler des objets qui n'ont rien à voir avec la choucroute!!!

                  Ce n'est pas l'arbre qui doit manipuler des goblins, ce sont tes goblins qui doivent manipuler l'arbre!

                  Chacun son job! que diable!

                  Ce dont tu me parles est une question de sémantique.

                  Bien sur que c'est de la sémantique, mais ne fais surtout pas l'erreur d'en sous-estimer le pouvoir!

                  car, comme disait l'autre "nommer, c'est créer" ou, pour reprendre un dialogue de film

                  Blisingr signifie le feu. C'est le feu. Le mot c'est la chose. Connait le mot et tu maitrise la chose

                  -- Eragon, 2004

                  Ou, plus prosaïquement : le lecteur de ton code ne dispose que des informations qu'il peut lire dans ton code pour se faire une idée "plus ou moins précise" de ce à quoi servent les différents éléments qu'il y rencontre.

                  Plus tu es précis dans les termes que tu utilise, plus il aura facile à se faire une idée précise de ce qui se fait

                  Mais si tu commences à appeler "quelque chose" qui manipule des goblins "EventXXX" ou "xxxEvent", comment veux-tu qu'il s'y retrouve, sachant que pour lui, un goblin n'est absolument pas un événement (et que l'inverse est tout aussi faux)

                  Sans oublier tous les problèmes que cela pourrait te confronter, parce que la relations EST-UN est souvent associée à l'héritage publique: une voiture EST-UN véhicule. Une usine ou une "maison de campagne" EST-UN bâtiment.

                  Mais tu peux tourner les choses comme tu veux : une relation proche de "Un goblin EST-UN événement" ou "Un événement EST-UN goblin" n'aura JAMAIS aucun sens!

                  Et j'y ai déjà répondu en te disant que je renommerai mon arbre.

                  Je me fous pas mal que tu l'appelle EventTree ou TreeEvent (quoi que j'aie une nette préférence pour la première solution)

                  Ce qui m'importe, c'est que le nom de ta classe permette à celui qui l'utilise de déterminer sans l'ombre d'un doute le type des éléments qu'elle va contenir (et accessoirement le rôle qu'elle joue ou non dans le choix de détruire les éléments devenus inutiles)

                  Mon arbre ne contiendra pas des événements mais les objets qui s'y rattachent, la propagation des événements ne se faisant que d'objets contenus à objets contenant.

                  Mais alors, c'est tout sauf un arbre d'événements!

                  Ce peut être un arbre de goblins, voir un arbre de Personnage (parce que oui: la relation "un goblin EST-UN personnage" peut avoir du sens ;) ) mais cet arbre (dont le type serait sans doute proche de CharacterTree pour la cause) aura déjà bien assez à faire en devant s'occuper de gérer les personnages (ou les goblins) sans que tu n'ailles essayer, en plus, de lui donner la responsabilité de s'occuper de la gestion des événements!

                  Il y a cinq principes, une loi et un conseil qu'il faut impérativement  respecter lorsque l'on développe une application.  Ce sont les principes SOLID et la loi de Déméter.  On en parle assez sur le forum pour qu'un petite recherche te permette d'apprendre tout ce que tu dois savoir sur ces principes et sur cette loi.

                  Et si tu as encore des questions sur le sujet, n'hésite pas à les poser: je me ferai une joie de t'expliquer ce qu'ils impliquent ;)

                  Quant au conseil... hé bien, je te l'ai déjà donné : chaque fois que tu dois donner un nom -- que ce soit à un type, à une variable (ou à un paramètre) ou à une fonction, veilles à ce que le nom que tu donnes permette à celui qui lira ton code de savoir exactement à quel usage la "chose" (comprends : le type, la variable ou la fonction) est destinée.

                  Tu peux me croire sur parole : le respect ce conseil peut te sauver les fesses bien plus souvent et bien plus rapidement que tu ne pourrais le croire ;)

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                    15 juin 2018 à 13:33:06

                    Permet moi de te rappeler mon précédent message:

                    amaurybenard a écrit:

                    Je suis d'accord avec toi. Mon arbre peut avoir diverses fonctions.

                    Je me contenterai donc de l'appeler disons: DoubleLinkedTree.

                    De plus cet arbre ne gérera pas les événements mais les Goblins et sera géré par le wrapper de Goblin Observer qui est mon écouteur d'événement, lequel propagera l'événement au Goblin étant constitué du Goblin émetteur.

                    Et oui, les Goblins utiliseront l'arbre passé en paramètre de leur constructeur, mais pour s'ajouter eux-même à cet arbre, par le biais de la méthode addChild que je compte implémenter, qui permettra de confectionner des composites de Goblins dont les composants seront sujets à la propagation des événements.

                    Ainsi, chaque nœud est un Goblin et non un événement et désolé si le nom que j'ai donné à la va vite ( TreeEvent ) a causé tant de dissonance cognitive.

                    Et, je me répète, je compte utiliser DoubleLinkedTree en tant que classe Template afin de rendre mon code plus évolutif.

                    J'espère que mon idée te séduit.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      15 juin 2018 à 14:11:47

                      amaurybenard a écrit:

                      Permet moi de te rappeler mon précédent message:

                      amaurybenard a écrit:

                      Je suis d'accord avec toi. Mon arbre peut avoir diverses fonctions.

                      Je me contenterai donc de l'appeler disons: DoubleLinkedTree.

                      De plus cet arbre ne gérera pas les événements mais les Goblins et sera géré par le wrapper de Goblin Observer qui est mon écouteur d'événement, lequel propagera l'événement au Goblin étant constitué du Goblin émetteur.

                      Soit!

                      Mais alors dit moi: à quoi correspond -- sémantiquement parlant -- le "goblin parent" ? Et les "gobelins enfants" ?

                      Je n'ai absolument rien contre le fait de créer des structures génériques, et je suis même un utilisateur de template assidu devant l'éternel.

                      Mais tu dois absolument comprendre que l'écriture d'un code n'est que la toute dernière étape, qui n'arrive qu'après un processus qui se doit d'être effectué scrupuleusement.

                      Le processus en question, c'est la conception. Et en termes de conceptions, il y a quatre règles à  respecter:

                      • Chaque notion présente dans l'analyse des besoin doit se retrouver dans l'analyse technique;  Chaque notion présente dans l'analyse technique doit trouver son équivalent dans le code;
                      • Chaque notion a son rôle à jouer,
                      • Un role particulier ne doit être pris en charge que par une seule notion
                      • Ce qui n'est pas nécessaire est inutile et te fait perdre du temps

                      Si tu arrives à justifier la présence d'un système parent/enfants pour les goblins (ou nous pouvons même parler de manière plus générale en parlant de "personnage", je ne verrai aucune objection à ce que tu utilise ton arbre pour mettre ce système en oeuvre.  Mais tu as intérêt à te montrer convaincant, car un "parce que j'ai envie" sera écarté d'office ;)

                      amaurybenard a écrit:

                      Et oui, les Goblins utiliseront l'arbre passé en paramètre de leur constructeur, mais pour s'ajouter eux-même à cet arbre, par le biais de la méthode addChild

                      Ca, c'est effectivement la manière correcte de t'y prendre ;)

                      amaurybenard a écrit:

                      Permet moi de te rappeler mon précédent message:

                      qui permettra de (1)confectionner des composites de Goblins dont (2)les composants seront sujets à la propagation des événements.

                      (1) Heu... C'est quoi un composite de goblin?

                      Si je suis très gentil et que je considère que cela peut exister (mais faudra que tu m'explique ce que c'est), il n'y a rien dans ton code qui laisse présager que ton goblin puisse intervenir de quelque facon que ce soit dans un patron de conception composite (car je présume que c'est à cela que tu penses??? )

                      (2) Non, que ce soit les goblin ou ce qui les composent, rien de tout cela n'a quoi que ce soit à voire avec la notion d'événement ou celle de la propagation des événements ;)

                      amaurybenard a écrit:

                      Ainsi, chaque nœud est un Goblin et non un événement et désolé si le nom que j'ai donné à la va vite ( TreeEvent ) a causé tant de dissonance cognitive.

                      Ca, ce n'est pas le plus grave!  Le plus grave, c'est que tu mélanges tes torchons (ta notion de goblin) avec tes serpillières (ta notion d'événements) : ce sont deux notions qui doivent être traitées de manière totalement distincte, et qui ne doivent se retrouver qu'à certains "points clés" bien spécifique pour permettre le passage de l'information.

                      Mais ton arbre (si tant est qu'il ait du sens pour des goblins... cf le début de cette intervention :D ) ne correspond clairement pas à ce fameux "point clé".

                      Au mieux, tu pourrais envisager d'utiliser cet arbre, au niveau du "point de jonction" (mon fameux "point clé" ;) ) pour permettre la connexion entre tes événements et tes goblins, mais cela ne doit certainement pas aller plus loin ;)

                      amaurybenard a écrit:

                      J'espère que mon idée te séduit.

                      Désolé, mais non!  Ton idée ne me séduit absolument pas.






                      • Partager sur Facebook
                      • Partager sur Twitter
                      Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                        15 juin 2018 à 23:12:48

                        D'accord, alors j'ai mal choisi le terme Goblin pour représenter une élément constitué d'objets et qui peut être une voiture par exemple.

                        Une voiture est constituée d'éléments comme d'un pare-brise, qui peut se fendre ou refléter le soleil mais également de roues qui peuvent se crever.

                        Parfois, ces éléments ( à la différence du pare-brise et de la roue ) sont eux-même constitués d'autres éléments.

                        Et ces objets, qui peuvent être changés sur une voiture, constituent le véhicule et sont représentables par des classes à part entière.

                        Ce véhicule peut donc être représenté comme un arbre d'objets semi-indépendants ( une roue suivra toujours - ou presque - la carrosserie ou plutôt inversement mais pourra se crever ), mais si la roue se crève la direction du véhicule est salement endommagée et dans tous les cas les éléments constitutifs du véhicule suivront l'agrégat qui a une inertie et ralentiront.

                        C'est cette interdépendance des objets que je souhaite implémenter ( une roue se crève => signal / slot ou événement  => la direction en est affectée ), grâce à ma classe Component ( et non plus Goblin ) qui sera constituée de feuilles et de composites comme dans le pattern Composite en effet.

                        J'espère avoir été convainquant et avoir répondu à tes points 1) et 2).:D

                        Le point clé de mon projet, là où doivent se rencontrer les Components ( ex Goblins, nom que j'avais choisi car c'était là le terme le plus proche de Sprite même si s'en étaient pas... :p ), les événements et l'arbre s'effectuera dans ma classe EventMulticaster.

                        EventMulticaster est étendue par Observer, qui est un wrapper de Component et qui broadcastera l'événement émis par le Component qu'il wrap, aux autres Components ( je sais, ma classe s'écoute elle-même mais comment faire autrement => imaginons un véhicule qui crève et qui ralentit les véhicules qui le précèdent ). Ça c'est une chose.

                        En second lieu, EventMulticaster fera que l'événement ainsi émis sera traité par le parent principal ( Component ) du Composite ayant émis l'événement en question grâce à un pointeur retournant ce même parent principal, lequel sera récupéré lors de l'exécution de la fonction find. Je m'explique:

                        Ce parent principal propage l'événement sur tous les descendants du sous-arbre qu'il constitue vis à vis de la fenêtre qui représente la racine de l'arbre.

                        Comment arrêter la fonction find afin qu'elle ne retourne que le parent principal qui nous intéresse? J'y travaille. J'ai ma petite idée...

                        Va savoir si j'utiliserai les signaux / slots ou les événements, je n'en sais rien pour le moment.

                        SI ce n'est qu'une question de préférence j'opterai pour les événements.

                        • Partager sur Facebook
                        • Partager sur Twitter
                          16 juin 2018 à 1:35:12

                          amaurybenard a écrit:

                          D'accord, alors j'ai mal choisi le terme Goblin pour représenter une élément constitué d'objets et qui peut être une voiture par exemple.

                          Une voiture est constituée d'éléments comme d'un pare-brise, qui peut se fendre ou refléter le soleil mais également de roues qui peuvent se crever.

                          Parfois, ces éléments ( à la différence du pare-brise et de la roue ) sont eux-même constitués d'autres éléments.

                          Et ces objets, qui peuvent être changés sur une voiture, constituent le véhicule et sont représentables par des classes à part entière.

                          Ce véhicule peut donc être représenté comme un arbre d'objets semi-indépendants ( une roue suivra toujours - ou presque - la carrosserie ou plutôt inversement mais pourra se crever ), mais si la roue se crève la direction du véhicule est salement endommagée et dans tous les cas les éléments constitutifs du véhicule suivront l'agrégat qui a une inertie et ralentiront.

                          C'est cette interdépendance des objets que je souhaite implémenter ( une roue se crève => signal / slot ou événement  => la direction en est affectée ), grâce à ma classe Component ( et non plus Goblin ) qui sera constituée de feuilles et de composites comme dans le pattern Composite en effet.

                          Le fait est que tu atteins là les limites de l'approche orientée objet "pure"

                          Pour gérer "efficacement" ce genre d'inter-dépendance, une approche de type ECS (Entity Component Systems )s'avère bien plus facile à maintenir ;)

                          J'espère avoir été convainquant et avoir répondu à tes points 1) et 2).:D

                          Ouaip, là tu as été convaincant dans l'expression des besoins que tu essayes de remplir.

                          Mais, comme je te l'ai dit, l'approche orientée objets n'est pas celle qui te permttra de faire les choses le plus facilement (et surtout de maintenir le bastringue facilement :P)

                          Le point clé de mon projet, là où doivent se rencontrer les Components ( ex Goblins, nom que j'avais choisi car c'était là le terme le plus proche de Sprite même si s'en étaient pas... :p ), les événements et l'arbre s'effectuera dans ma classe EventMulticaster.

                          Et comme je l'ai sous-entendu dans une autre intervention, avoir une classe (ou une hiérarchie de classes) qui doit connaitre tous tes composants et tous tes événements pour savoir à quel composant faire parvenir quel événement, c'est vraiment moyen moyen, ne serait-ce que parce que tu vas assister à un couplage fort et massif entre tes composant, tes événements et ton EventMulticaster et que ca deviendra rapidement ingérable.

                          Encore une fois, un système de signaux et de slots me semble beaucoup plus souple ;)

                          EventMulticaster est étendue par Observer, qui est un wrapper de Component et qui broadcastera l'événement émis par le Component qu'il wrap, aux autres Components ( je sais, ma classe s'écoute elle-même mais comment faire autrement => imaginons un véhicule qui crève et qui ralentit les véhicules qui le précèdent ). Ça c'est une chose.

                          A ce stade de la discussion, tu me sembles essentiellement focalisé sur le patron "composite" et "observateur".

                          Et je ne suis même pas sur que tu appréhende correctement ce qu'est réellement la notion d'événement :p

                          Or, il y a une chose importante à savoir que l'on n'apprend pas forcément au sujet des patrons de conception lorsqu'on les étudie : malgré le fait qu'on puisse les étudier "séparément" (on peut se faire une idée de ce qu'est un observateur en ne s'intéressant qu'à l'observateur), la plupart des patrons de conceptions (proposés en 1998 par le GoF) dépendent "d'autres patrons" pour leur mise en oeuvre "réelle".

                          L'impression que me laissent ces deux discussions, c'est que tu t'es lancé dans l'écriture de code sans avoir correctement réfléchis au tenants et aboutissants; sans avoir pu te créer ce que les anglais appellent une big picture suffisamment précise de la manière dont tous tes besoins devront s'intégrer.

                          Pourquoi? Parce que malgré toute mon expérience (et je peux t'assurer que j'en ai :D ), les deux discussions n'ont pas suffit à me permettre de me faire ma propre big picture précise de ce que tu essayes de faire.

                          Je peux me tromper, bien sur (je suis humain, je fais des erreurs, comme n'importe qui), mais cette impression est, sinon confirmée, à tout le moins confortée, par le fait que, pour essayer de me faire comprendre ce que tu voulais faire, il n'y a pas une seule des classes dont tu ait parlé à l'origine pour laquelle tu n'a pas changé de nom au moins une fois (et parfois d'avantage).

                          En un mot comme en cent, j'ai l'impression que tu t'es précipité; que tu as sauté les étapes les plus importante du développement logiciel qui sont l'analyse des besoins et la conception :p

                          Sincèrement, si j'avais un seul conseil à te donner ici et maintenant, ce serait STOP! Arrête de courir, respire un bon coup, et recommence correctement depuis le début:

                          1- quels sont les besoins à remplir?

                          2- si les besoins sont "créer un mini rgp" (ou quelque description similaire) essaye d'en fournir une description (beaucoup) plus détaillée

                          3- Passes à l'analyse technique : chaque nom (groupe nominal) qui apparait dans l'analyse des besoins doit  être représenté par une notion (sans doute un type de donnée personnalisé) dans ton analyse technique; chaque verbe (groupe verbal) qui apparait dans l'analyse des besoins doit être représenté par un comportement dans ton analyse technique

                          4- commence à écrire le code, en commencant par les éléments les plus simples, en veillant à ce que chaque type et chaque comportement que tu auras identifié dans ton analyse technique trouve son équivalent dans le code

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait

                          passage de pointeur

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                          • Editeur
                          • Markdown