Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Polymorphisme] - Problème de classes entre header

Sujet résolu
    1 août 2007 à 1:26:53

    Salut à tous !

    Alors voila, j'ai un problème avec 4 classes séparées dans deux headers : il y a deux classes dans menu.h et deux classe dans linked_list.h.

    Dans menu.h se trouvent la class Menu (on s'en fou ici), et la classe Composed.
    Dans linked_list.h se trouvent la classe Node (le noeud d'une liste chaînée), et la classe Linked(la liste chaînée).

    Linked a besoin de la SDL et un de ses attribus et un pointeur sur Node.
    Node a besoin de la SDL mais aussi de la délcaration de la classe Composed (le but étant de faire des liste chaînées de Composed).

    Donc j'ajoute les includes SDL et l'include menu.

    Maintenant, dans menu.h, ma classe Menu instancie en attribu Linked. J'inclue donc linked_list.h. Là, bien évidemment, erreur de redéfinition des headers... Je fais donc cela :

    // "menu.h"

    #ifndef LINKED_LIST_H
    #define LINKED_LIST_H

    //#include <SDL/SDL.h>
    #include "linked_list.h"

    // Déclaration

    #endif
     


    et ça

    // "linked_list.h"

    #ifndef MENU_H
    #define MENU_H

    #include <SDL/SDL.h>
    #include "menu.h"

    // Déclaration

    #endif
     


    Il me sort comme erreur que le pointeur créé en attribu dans Node pointe sur un objet qui n'est pas connu (à savoir Composed)

    Can somebody help me ? :(
    • Partager sur Facebook
    • Partager sur Twitter
      1 août 2007 à 1:40:08

      FAQ C++ de developpez -> passage sur les dépendances circulaires.

      Sinon ... std::list<> marche bien. Et la généricité lui permet de ne pas introduire de dépendances inutiles.
      • Partager sur Facebook
      • Partager sur Twitter
      C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
        1 août 2007 à 1:41:49

        Ok mais mes protections sont bonnes pourtant ? Il n'y a rien de circulaire ici, si ?
        • Partager sur Facebook
        • Partager sur Twitter
          1 août 2007 à 1:59:06

          Hum....
          L -> N -> C
          L <------ M

          M et C sont ensembles, L et N aussi.
          Il y a bien de jolies flêches qui se croisent.

          Soit sépare C et M -- à conditon qu'eux même n'aient pas une dépendance que tu n'as pas exprimée dans ton message.

          Soit, exploite un des paradigmes majeurs du C++, à savoir la généricité. Voire mieux utilise sa SL.

          Soit détermine quand tu as besoin des déclarations et quand tu as besoin des définitions pour reprendre tes fichiers d'en-tête en conséquence.

          Dans l'ordre de préférence des solutions : 2, 1, 3.
          • Partager sur Facebook
          • Partager sur Twitter
          C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
            1 août 2007 à 2:21:33

            Ok merci

            Mais pour des raisons purement confortables, je ne souhaite pas séparer mes classes. Menu doit être dans menu.h et Composed aussi.

            Donc si je retrace mon code, ça donne ça :

            on entre dans menu.h et l'on voit que si LINKED_LIST_H n'est pas définie alors on le définit et l'on inclue linked_list.h. On va jeter un coup d'oeil dans linked_list.h, si MENU_H n'est pas définie alors on le définit et l'on inclue menu.h. De retour dans menu.h, si LINKED_LIST_H n'est pas définit, on sait ce qu'il faut faire. Hors il n'est pas défini. Donc il n'y a rien à faire !

            Je poste le code en entier, si quelqu'un peu m'aider ....

            // menu.h

            #ifndef LINKED_LIST_H
            #define LINKED_LIST_H

            #include <SDL/SDL.h>
            #include "linked_list.h"

            class Composed
            {
                public :
                    Composed(const char *text, unsigned short int y);
                    Composed(const Composed &object2C);
                    ~Composed();

                    void Display(SDL_Surface *screen);
                    bool Getarea(SDL_Surface *screen, SDL_Event event);/* Return a bool {True : the cursor is
                                                                                                                                                     *in the area of the composed}
                                                                                                                    * {False : other} */

                    bool Isclik(SDL_Surface *screen, SDL_Event event); /* Reurn a bool {True : The clik in
                                                                                                                                                     * one of the composed}
                                                                     * {False : Other} */


                private :
                    // SDL_Surface*
                    SDL_Surface *composed;
                    // Positions
                    SDL_Rect posComposed;
                    // Alpha value
                    Uint8 valueAlph;
            };

            class Menu
            {
                public :
                    Menu(bool head);
                    ~Menu();

                    unsigned short int Translatedssl(SDL_Surface *screen);
                    void Launch(SDL_Surface *screen);
                    void Newcomposed(const char *cName, unsigned short int y)
                    void Display(SDL_Surface *screen); // Display the menu on screen
                    void Actualiz(SDL_Surface *screen); // Actualise screen
                    void Changecursor(SDL_Surface *screen, const char *mode);
                    bool Cursor(SDL_Surface *screen, SDL_Event *event);

                private :
                    unsigned short int nmbComposed;
                    // Surfaces
                    SDL_Surface *hide;
                    SDL_Surface *ssl;
                    SDL_Surface *cursor01;
                    SDL_Surface *cursor02;
                    // Composed
                    Composed *comp[5]; // Will be remplace by a linked list
                    // Positions
                    SDL_Rect null;
                    SDL_Rect posSsl;
                    SDL_Rect posCursor;
                    // Event
                    SDL_Event event;
                    bool finish;
                    bool cursSpecial;
            };

            #endif
             


            et

            // linked_list.h

            #ifndef MENU_H
            #define MENU_H

            #include <SDL/SDL.h>
            #include "menu.h"

            class Node
            {
                public :
                    Node(const char *cName = NULL, unsigned short int y = 0);
                    ~Node();

                    void Insert(const char *cName, unsigned short int y);
                    void Display(SDL_Surface *screen, bool longation);
                    Node Next();

                private :
                    Composed *_comp; // Erreur de type ici ...
                    Node *_ptr_Next;
            };

            class Linked
            {
                public :
                    Linked();
                    ~Linked();

                    void Add(const char *cName = NULL, unsigned short int y = 0);
                    void Display(SDL_Surface *screen);
                    Node * operator[](unsigned short int offset);

                private :   
                    Node *_head;
                    unsigned short int _offset;
            };

            #endif
             


            Voila :(
            • Partager sur Facebook
            • Partager sur Twitter
              1 août 2007 à 2:46:46

              Ça ne changera rien à ton problème mais bon, ce que je ne comprends pas c'est : pourquoi tu définies la variable MENU_H_ dans Linked_List.h et LINKED_LIST_H_ dans Menu.h ?

              En général, la variable du #ifndef/#define porte le nom du header dans lequel il est défini...

              Aussi, tu peux "essayer" de mettre tes #include AVANT le #ifndef/#define...
              • Partager sur Facebook
              • Partager sur Twitter
                1 août 2007 à 3:32:10

                Non et Non!

                Je crois que Imghs a par deux fois proposé des solutions très éclairées mais -Skypers- tu ne semble pas l'écouté

                1. je choisirais la classe std::list

                2. Si je voulais vraiment coder moi-même ma liste chaînée (je crois que c'est ton cas) j'utiliserai la généricité (les templates) et je ferais de ma liste chainées une liste de n'importe quoi (comme std::vector)

                3. Pour la solution simple c'est dans la FAQ developpez.com et c'est bien une dépendance circulaire... Cela peut être évité en organisant très bien son développement ou en utilisant un #include dans un des fichiers et une signature de la classe dans l'autre.

                fichier_dep1.h
                #ifndef ...
                #define ...

                #include "fichier_dep2.h"

                class Classe_dep1
                {
                //...
                };

                #endif
                 


                fichier_dep2.h
                #ifndef ...
                #define ...

                class Classe_dep1;

                class Classe_dep2
                {
                //...
                };

                #endif
                 


                Serait-ce trop demander d'au moins essayer les solutions proposées et de faire un peu de recherche? N'y voit aucune méchanceté c'est seulement que je t'ai trouvé un peu lâche sur ce coup là -Skypers- :\ Bonne continuation, tu fais beaucoup de progrès depuis que je te vois sur le site.
                • Partager sur Facebook
                • Partager sur Twitter
                  1 août 2007 à 11:52:54

                  Merci beaucoup.

                  Désolé de paraître lâche, je n'écarte pas vos solutions, bien au contraire ! Seulement je ne connais pas list de l'espace de nom standard et je débute à peine les bases des modèles templates (je n'apprends pas le C++ sur ce site, ni en cours (je n'ai que 15 ans :( ) mais avec des bouquins et en cherchant sur le net).

                  Aussi, je voulais vous le dire plus tôt, mes listes chaînées ne sont pas optimisées. Je veux dire qu'aucunes notions particulières n'y sont introduites.

                  Voila, donc en fait il faut que je place l'include avant le if not defined ?

                  Et pour répondre à psychoh13, je définissais en fait MENU_H dans linked_list.h parce que l'inclusion est menu.h.

                  Je m'en vais pendant 4/5 jours donc je ne pourrais pas vous répondre
                  • Partager sur Facebook
                  • Partager sur Twitter
                    1 août 2007 à 14:30:58

                    Citation : -Skypers-

                    Et pour répondre à psychoh13, je définissais en fait MENU_H dans linked_list.h parce que l'inclusion est menu.h.



                    Bah oui, tu viens de me donner une raison de plus de prouver ton manque de logique...
                    On définit la variable HEADER_H_ pour empêcher la multi-inclusion du fichier Header.h... Et non pas parce qu'on inclut HEADER_H_ dans un autre fichier...
                    • Partager sur Facebook
                    • Partager sur Twitter
                      1 août 2007 à 15:47:37

                      Pour ce qui est de la STL tu peux facilement cliquer sur le lien GotAPI.com dans ma signature, tout y est

                      En suite pour la recherche tu peux aller voir comment faire une classe templates et éliminer cette dépendance inutile.

                      finalement l'inclusion avant les defines ne changerons rien... c'est la technique que j'ai décrit plus haut qui fonctionnera. Mais psychoh13 a absolument raison que l'en-tête se définie elle-même, ce n'est pas le fichier qu'il l'inclu qui doit s'arranger pour le définir.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        4 août 2007 à 3:25:53

                        Okay merci beaucoup ! Mais ça ne marche toujours pas...

                        Je vais essayer de me pencher encore plus sur la question, mais je ne comprends toujours pas, est-ce que quelqu'un peut m'expliquer pourquoi mes inclusions ne fonctionnent pas ?
                        • Partager sur Facebook
                        • Partager sur Twitter
                          4 août 2007 à 6:36:17

                          Ok prend deux en-têtes bidon(ne)s :

                          //head1.h
                          #ifndef _HEAD1_H_
                          #define _HEAD1_H_
                          #include "head2.h"

                          class Bidon1
                          {
                              Bidon2 m_b2;
                              //...
                          }
                          #endif //_HEAD1_H_
                           

                          //head2.h
                          #ifndef _HEAD2_H_
                          #define _HEAD2_H_
                          #include "head1.h"

                          class Bidon2
                          {
                              Bidon1 m_b1;
                              //...
                          }
                          #endif //_HEAD2_H_
                           


                          Tu es en accord avec moi Bidon1 et Bidon2 sont des classes inter-dépendantes...

                          voici ce que fait le précompilateur :

                          1. Il ouvre les fichiers en ordre d'apparition dans un fichier cpp(disons que head1.h vient avant head2.h)

                          2. Il lit et interprète les instructions le concernant :
                          ligne 1 : est-ce que _HEAD1_H_ est défini : NON (on entre)
                          ligne 2 : Définit : _HEAD1_H_
                          ligne 3 : inclus "head2.h" ce qu'il fait immédiatement :
                          // ligne 2 : ici _HEAD1_H_ est défini
                          #ifndef _HEAD2_H_
                          #define _HEAD2_H_
                          #include "head1.h"

                          class Bidon2
                          {
                              Bidon1 m_b1;
                              //...
                          }
                          #endif //_HEAD2_H_

                          class Bidon1
                          {
                              Bidon2 m_b2;
                              //...
                          }
                          #endif //_HEAD1_H_

                          // reste du premier fichier cpp ayant inclus head1.h
                           


                          et il continu :
                          ligne 3 : est-ce que _HEAD2_H_ est défini : NON (on entre)
                          ligne 4 : Définit : _HEAD2_H_
                          ligne 3 : inclus "head1.h" ce qu'il fait immédiatement :
                          // ligne 2 : ici _HEAD1_H_ est défini
                          // ...
                          // ligne 4 : ici _HEAD2_H_ est défini
                          #ifndef _HEAD1_H_
                          #define _HEAD1_H_
                          #include "head2.h"

                          class Bidon1
                          {
                              Bidon2 m_b2;
                              //...
                          }
                          #endif //_HEAD1_H_

                          class Bidon2
                          {
                              Bidon1 m_b1;
                              //...
                          }
                          #endif //_HEAD2_H_

                          class Bidon1
                          {
                              Bidon2 m_b2;
                              //...
                          }
                          #endif //_HEAD1_H_

                          //fichier cpp
                           


                          (tu commences à comprendre?)
                          ligne 5 : est-ce que _HEAD1_H_ est défini : OUI! on entre pas alors le précompilo supprime tout ce qui a entre #ifndef et #endif (voir exemple en bas)
                          ligne X : supprime les lignes contenant les #endif dans lequels nous sommes passés

                          (avec en commentaire les pensées d'un compilateurs solitaire :p)
                          class Bidon2
                          {
                              Bidon1 m_b1; // Ici le compilateur plante : je ne connais pas Bidon1
                              //...
                          }

                          class Bidon1
                          {
                              Bidon2 m_b2;
                              //...
                          }

                          //fichier cpp
                           


                          Voilà à quoi ressemble le fichier prêt à compiler... mais il n'est pas valide... maintenant si tu n'avais pas inclus head1.h dans head2.h mais utilisé la technique que je t'ai montré

                          //head2.h
                          #ifndef _HEAD2_H_
                          #define _HEAD2_H_

                          class Bidon1;

                          class Bidon2
                          {
                              Bidon1 m_b1;
                              //...
                          }
                          #endif //_HEAD2_H_
                           


                          Ton fichier final aurait ressemblé à :

                          (retrouvons le compilateur solitaire et ses pensées)
                          class Bidon1; // signature de Bidon1 vue et conservée

                          class Bidon2 // signature de Bidon2 vue et conservée
                          {
                              Bidon1 m_b1; // Je connais une classe Bidon1
                              //...
                          }

                          class Bidon1 // Extension de la classe Bidon1 pré-définie
                          {
                              Bidon2 m_b2; // Je connais une classe Bidon2
                              //...
                          }

                          //fichier cpp
                           


                          ;) j'espère seulement que je ne me suis pas mélangé dans mes 2 et mes 1 quelque part...
                          • Partager sur Facebook
                          • Partager sur Twitter
                            4 août 2007 à 14:01:29

                            Okay ! Merci beaucoup je vais essayer ça !

                            EDIT : Okay c'est bon ça marche merci beaucoup je ne savais pas que l'on pouvait "prototyper" les classes &#94;&#94; Merci !

                            Mais j'ai un autre problème un peu moins évident, j'ai cherché pendant pas mal de temps hier soir je ne trouve pas de solutions. L'une de mes classe, Node, a un constructeur qui alloue dynamiquement de la mémoire à un pointeur sur Composed. Cela appelle donc le constructeur de copie de Composed. Composed possède un pointeur de type SDL_Surface, vous comprenez que je suis embêté ! J'ai donc reécris le constructeur de copie ainsi :


                            Composed::Composed(const Composed &object2C)
                            {
                                posComposed = object2C.posComposed;
                                valueAlph = object2C.valueAlph;

                                composed = new SDL_Surface; // Allocation ici

                            }


                            Seulement voila, voici le constructeur surchargé de Composed :


                            Composed::Composed(const char *text, unsigned short int y)
                            {
                                TTF_Font *font = TTF_OpenFont("alphamalemodern.ttf", y);
                                SDL_Color colour = {0, 255, 0};

                                // Creating of SDL_Surface*;
                                composed = TTF_RenderText_Blended(font, text, colour); // Bog ICI
                                   
                                TTF_CloseFont(font);

                                posComposed.x = (W_WIDTH / 2) /*- (composed->w / 2)*/; // composed's position
                                posComposed.y = y;

                                //Initialization of alpha value
                                valueAlph = 0;
                                   
                            }


                            Le compilateur plante donc lorsque j'essaie de modifier le pointeur composed. Pourtant, je suis obligé de le modifier dans le constructeur, et je ne peux pas ne pas allouer dynamiquement dans le constructeur de copie sinon les pointeurs pointeront tous sur le même SDL_Surface !

                            Donc je ne sais pas quoi faire &#58;&#40;
                            • Partager sur Facebook
                            • Partager sur Twitter
                              4 août 2007 à 19:27:09

                              Tout va bien, tu as la bonne technique dans ton constructeur de copie mais tu dois créer un NOUVEAU SDL_Surface en mémoire et copié ses données afin d'en créer une copie conforme de l'original.

                              Par contre, je ne comprend pas ton constructeur paramétrique : pourquoi modifier le pointeur de ton objet qui n'existe pas?1. C'est impossible (sauf en passant par this mais cela reste inutile)
                              2. Tu semble mélangé dans le rôle de tes contructeurs

                              Citation : -Skypers-

                              Mais j'ai un autre problème un peu moins évident, j'ai cherché pendant pas mal de temps hier soir je ne trouve pas de solutions. L'une de mes classe, Node, a un constructeur qui alloue dynamiquement de la mémoire à un pointeur sur Composed. Cela appelle donc le constructeur de copie de Composed. Composed possède un pointeur de type SDL_Surface, vous comprenez que je suis embêté !



                              Non je ne comprend pas ton embêtement :p on va simplifier le tout. Premièrement ta classe Node a un pointeur sur un Composed. Lorsque tu créer un Node tu demande à ton constructeur de créer un Composed. Tu appels donc sont constructeur lors du new(par défaut ou paramétrique selon ce que tu fais). La seule raison pour laquelle un constructeur de copie serait appelé c'est que tu passe comme paramètre un autre Composed déjà construit.

                              Voilà pour la classe Node ce problème (si s'en était un) ne concerne que cette classe et n'a aucun rapport avec le code que tu nous a montré (C'est la force de la POO bien utilisée)

                              Je ne connais pas vraiment la SDL mais je crois que pour copier une SDL_Surface tu peux utiliser SDL_BlitSurface()... alors après le new tu peux faire un appel à cette fonction.

                              Pourquoi ça plante dans le constructeur de copie? je n'arrive pas a le voir comme ça mais tu pourrais peut-être renommé ton pointeur qui n'est pas très auto-documenté. tu peux l'appeler surface ou m_pSurface pour faire très standard : m_ = membre de la classe; p = pointeur; Surface = nom auto-documenté nous signalant qu'il s'agit d'un pointeur membre sur une surface; ;)
                              • Partager sur Facebook
                              • Partager sur Twitter
                                4 août 2007 à 20:10:32

                                Merci beaucoup de m'aider !

                                Pour les 'm', 'p', 'r' (ref) et tout ça, je connais bien, mais je n'utilise pas cette syntaxe. Au début je mettais i_variableMembre mais c'était bordélique donc _variableMembre me convient mais c'est vrai que le nom de ma variable membre est le même que celui de la classe, donc je vais modifier ça.

                                Donc en fait, si je comprends bien, un appel à new n'appelle pas obligatoirement le constructeur de copie ? Il me semblait pourtant que si...

                                Si je comprends bien, l'implémentation de mon constructeur de copie ne sert ici à rien ?

                                Sinon SDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect); permet juste de "coller" les surface sur l'écran (en gros :p )

                                Je vais essayer de me passer du constructeur de copie et voir comment je peux m'y prendre autrement ^^
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  4 août 2007 à 20:56:38

                                  en fait tu as besoin du constructeur de copie

                                  ton new appel ton constructeur de base s'il n'y a pas de paramètre, de copie si tu lui passe un objet de même classe et un constructeur paramétrique si tu lui passe tout autre paramètre.

                                  Le constructeur de copie sert à faire une copie d'un autre objet de même classe au moment de sa création.

                                  Et bien pour SDL_BlitSurface j'ai seulement regarder sur Google est c'est la technique que j'ai vu pour copier une surface dans une autre. Si tu regarde bien les paramètres tu vas voir que tu as un pointeur source et un destination donc pour moi ce peut fonctionner, tu peux rechercher toi-même ma connaissance en SDL est extrêmement limitée.

                                  les préfixe de type ne sont pas nécessaire mais les "m_" nous permettent de t'aider mieux, tu peux seulement les utiliser pour le code que tu veux nous montrer c'est standard donc plus facile pour nous de comprendre ce que tu fais avec ton code ;)
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    4 août 2007 à 21:43:28

                                    NB : il y a deux façons d'appeler un constructeur de copie :
                                    Explicitement :

                                    MaClasse objetDeMaClasse(autreObjetDeMaClasse);


                                    Implicitement :

                                    MaClasse objetDeMaClasse = autreObjetDeMaClasse;


                                    Le symbole "=" ici ne correspond pas à la surcharge de l'opérateur d'affectation "=". Ici il s'agit d'une initialisation, c'est-à-dire de l'affectation d'une valeur à une variable lors de sa déclaration. Ici c'est donc le constructeur de copie qui est utilisé.
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      5 août 2007 à 5:30:18

                                      Oui j'ai lu un long chapitre dans un bouquin sur ça (constructeur de copie et opérateur d'affectation).

                                      C'est bon le problème est résolu ! En fait le problème était bien plus étendu : problème d'opérateur d'indexation, valeur par défaut pour des paramètres de méthode manquante... C'est bon tout marche impec !! Les listes chaînées sont vraiment efficaces je peux travailler en souplesse et assurer l'extensibilité et la maintenabilté de code, c'est énorme !

                                      Merci à tous !

                                      Et pour cette histoire de constructeur de copie, je n'en avais donc pas besoin. Si ? Ca marche très bien sans, mais de toutes manières, quand on fait ça :

                                      composed = new SDL_Surface;


                                      Il n'y a pas de "copie" du tout donc.

                                      Par contre si je fais ça :


                                      SDL_Surface *ptr = objectToCopy->Getsurface();
                                      composed = new SDL_Surface(*ptr);


                                      Là il est alloué dynaniquement de l'espace dans la mémoire heap pour stocker un nouveau SDL_Surface* qui sera une copie intégrale de ce sur quoi pointe la surface locale, le tout renvoyé au pointeur composed !

                                      Ca doit être ça mais je suis un peu fatigué vu l'heure lol donc si j'ai fais une erreur de syntax (*) dites le moi &#58;&#41;

                                      J'aimerai bien aussi vous envoyer l'exécutable pour que vous dites ce que vous en pensez mais je compile sous Vista alors est-ce que ça marchera sous XP aussi ?

                                      Voila bonne programmation à tous !
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        5 août 2007 à 9:30:10

                                        Quand on n'a pas beson de copier des objets, plutôt que de se prendre le choux à écrire deux fonctions inutiles, on interdit la copie.

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
                                          5 août 2007 à 14:03:59

                                          Sinon tu n'as pas une idée comment je pourrais développer mon logiciel pour qu'il fonctionne sous tous les versions OS Windows ?
                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          [Polymorphisme] - Problème de classes entre header

                                          × 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