Partage
  • Partager sur Facebook
  • Partager sur Twitter

héritage

Sujet résolu
    8 août 2007 à 21:46:11

    salut

    alors je commence les notions d'héritage car j'aimerais créer un rpg et je ne différencie pas quelque fonction comme celle du déplacement, etc cependant j'ai un petit problème

    1. #include <iostream>
    2. #include <SDL/SDL.h>
    3. #include <SDL/SDL_image.h>
    4. #include <SDL/SDL_ttf.h>
    5. #include "Classes.h"
    6. #include "constante.h"
    7. //--------------------------classe Pnj----------------------------------------------------//
    8. Pnj::Pnj(SDL_Rect depart)
    9. {
    10.            _image[0] = new SDL_Surface;
    11.            _image[1] = new SDL_Surface;
    12.            _image[2] = new SDL_Surface;
    13.            _image[3] = new SDL_Surface;
    14.            _position.x = depart.x;
    15.            _position.y = depart.y;
    16. }
    17. Pnj::~Pnj()
    18. {
    19.            delete[] _image;
    20. }
    21. //---------------------------------classe allies------------------------------------------//
    22. Allies::Allies(SDL_Rect depart)
    23. {
    24.            _image[0] = new SDL_Surface;
    25.            _image[1] = new SDL_Surface;
    26.            _image[2] = new SDL_Surface;
    27.            _image[3] = new SDL_Surface;
    28.            _position.x = depart.x;
    29.            _position.y = depart.y;
    30. }
    31. Allies::~Allies()
    32. {
    33.            delete[] _image;
    34. }


    lorsque je compile ça avec les autres feuille de codes qui vont avec il me signal une erreur

    erreur : no matching function for call to `Pnj::Pnj()'

    je crois qu'il me dis qu'il n'y a pas de fonction qui appelle le constructeur de la classe mère mais je suis pas sûr de bien comprendre :p si quelqu'un pouvait m'aider

    merci d'avance icare

    P.S: le fichier .h
    1. #ifndef DEF_PNJ
    2. #define DEF_PNJ
    3. class Pnj
    4. {
    5.       protected:
    6.       SDL_Surface *_image[4];
    7.       SDL_Rect _position;
    8.       public:
    9.       Pnj(SDL_Rect depart);
    10.       ~Pnj();
    11. };
    12. class Allies:public Pnj
    13. {
    14.       protected:
    15.       public:
    16.       Allies(SDL_Rect depart);
    17.       ~Allies();
    18. };
    19. #endif
    • Partager sur Facebook
    • Partager sur Twitter
      8 août 2007 à 21:53:14

      Bonsoir.

      Il faut que tu définisse ton costructeur par défaut.
      Il me semble que cela est due à l'héritage(à vérifier).

      Mais pas besoin de spécifier quoique ce sois dans le constructeur par défaut.

      Sinon essaie en faisant ceci :

      1. Allies::Allies(SDL_Rect depart) : Pnj::Pnj(depart)
      2. {
      3.            _image[0] = new SDL_Surface;
      4.            _image[1] = new SDL_Surface;
      5.            _image[2] = new SDL_Surface;
      6.            _image[3] = new SDL_Surface;
      7.            _position.x = depart.x;
      8.            _position.y = depart.y;
      9. }
      • Partager sur Facebook
      • Partager sur Twitter
        8 août 2007 à 22:00:34

        PS: tes libérations ne sont pas bonnes.
        • 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.
          8 août 2007 à 22:02:31

          Le problème vient de l'héritage, quand tu va créer un objet de la classe fille il va appeller le constructeur de la classe mère :
          1. #include <iostream>
          2.       #include <SDL/SDL.h>
          3.       #include <SDL/SDL_image.h>
          4.       #include <SDL/SDL_ttf.h>
          5.       #include "Classes.h"
          6.       #include "constante.h"
          7.       //--------------------------classe Pnj----------------------------------------------------//
          8.       Pnj::Pnj(SDL_Rect depart)
          9.       {
          10.                  _image[0] = new SDL_Surface;
          11.                  _image[1] = new SDL_Surface;
          12.                  _image[2] = new SDL_Surface;
          13.                  _image[3] = new SDL_Surface;
          14.                  _position.x = depart.x;
          15.                  _position.y = depart.y;
          16.       }
          17.       Pnj::~Pnj()
          18.       {
          19.                  delete[] _image;
          20.       }
          21.       //---------------------------------classe allies------------------------------------------//
          22.       Allies::Allies(SDL_Rect depart) : Pnj(depart)
          23.       {
          24.                  _image[0] = new SDL_Surface;
          25.                  _image[1] = new SDL_Surface;
          26.                  _image[2] = new SDL_Surface;
          27.                  _image[3] = new SDL_Surface;
          28.                  _position.x = depart.x;
          29.                  _position.y = depart.y;
          30.       }
          31.       Allies::~Allies()
          32.       {
          33.                  delete[] _image;
          34.       }


          1. #ifndef DEF_PNJ
          2.       #define DEF_PNJ
          3.       class Pnj
          4.       {
          5.             protected:
          6.             SDL_Surface *_image[4];
          7.             SDL_Rect _position;
          8.             public:
          9.             Pnj(SDL_Rect depart);
          10.             virtual ~Pnj();
          11.       };
          12.       class Allies:public Pnj
          13.       {
          14.             protected:
          15.             public:
          16.             Allies(SDL_Rect depart);
          17.             ~Allies();
          18.       };
          19.       #endif
          • Partager sur Facebook
          • Partager sur Twitter
          FaQ : Fr | En 1 2 | C++11 | Template || Blog : Deloget | C++|Boost--Dev | C++Next | GotW || Installer Boost
            8 août 2007 à 22:03:33

            Je ne suis pas certain mais à mon avis le problème vient du fait que tu définis un constructeur prenant des paramètres pour une classe dérivée et que celui-ci ne fait pas appelle explicitement au constructeur de la classe de base.

            Edit: grillé :colere2:
            • Partager sur Facebook
            • Partager sur Twitter
            Inkamath on GitHub - Interpréteur d'expressions mathématiques. Reprise du développement en cours.
              8 août 2007 à 22:07:28

              Les deux grillé en plus :)
              Pour les libérations il faut faire :
              1. for(int i = 0; i < nbImages; i++)
              2.     delete _images[i];


              Mais bon c'est plus simple d'utiliser un std::list ou un std::map et un iterateur pour la libération ;)
              • Partager sur Facebook
              • Partager sur Twitter
                8 août 2007 à 22:12:12

                vous ètes sûr pour les libérations ? parce que dans le tutorial de mattéo il m'a semblé avoir vu que pour libérer un tableau delete[] suffisait

                une autre question si y a un constructeur par defaut y a aussi un destructeur par defaut ou les fonctions qui marchent dans le même style ?
                • Partager sur Facebook
                • Partager sur Twitter
                  8 août 2007 à 22:25:08

                  Pour les libération, quand tu alloue avec new tu libère avec delete, et quand tu utilise new[] tu libère avec delete[], il ne faut pas allouer avec un et libèrer avec l'autre comme tu as fait ic.

                  Il n'y as qu'un seul et unique destructeur par class : ~nom_de_la_class();
                  • Partager sur Facebook
                  • Partager sur Twitter
                  FaQ : Fr | En 1 2 | C++11 | Template || Blog : Deloget | C++|Boost--Dev | C++Next | GotW || Installer Boost
                    8 août 2007 à 22:27:36

                    Sauf que là, ce n'est pas un tableau dynamique d'objets, c'est un tableau statique de pointeurs pointant chacun vers un objet alloué dynamiquement.
                    C'est un peu beaucoup différent.


                    Il peut y avoir 150 constructeurs différents, mais il n'y a qu'un seul destructeur.
                    Dans tous les cas, le chainage est obligatoire. Implicite pour le destructeur. Implicite vers le constructeur par défaut si rien n'est précisé ; explicite si précisé.
                    • 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.
                      8 août 2007 à 22:31:02

                      Citation : atoboldom

                      Les deux grillé en plus :)
                      Pour les libérations il faut faire :

                      1. for(int i = 0; i < nbImages; i++)
                      2.     delete _images[i];



                      Mais bon c'est plus simple d'utiliser un std::list ou un std::map et un iterateur pour la libération ;)


                      delete[] est la bonne manière a faire...

                      quoi que ce sont des SDL_Surface, alors peut-être vaudrait mieux faire SDL_FreeSurface.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        8 août 2007 à 22:49:21

                        Citation : lmghs

                        Il peut y avoir 150 constructeurs différents, mais il n'y a qu'un seul destructeur.Dans tous les cas, le chainage est obligatoire. Implicite pour le destructeur. Implicite vers le constructeur par défaut si rien n'est précisé ; explicite si précisé.



                        pardonne mon inculture mais le tutorial que j'ai trouvé parle pas de chainage ^^ c'est quoi en fait ?

                        ceci dis je pensais si je fais une fonction deplacer dans ma classe mere et que j'en refais une dans la classe fille je dois aussi faire ce truc ?

                        1. void deplacer(int orientation) : Pnj(orientation)

                        (exemple vite fais

                        merci encore pour vos réponse
                        • Partager sur Facebook
                        • Partager sur Twitter
                          8 août 2007 à 22:54:54

                          Citation : icare14

                          Citation : lmghs

                          Il peut y avoir 150 constructeurs différents, mais il n'y a qu'un seul destructeur.Dans tous les cas, le chainage est obligatoire. Implicite pour le destructeur. Implicite vers le constructeur par défaut si rien n'est précisé ; explicite si précisé.



                          pardonne mon inculture mais le tutorial que j'ai trouvé parle pas de chainage ^^ c'est quoi en fait ?

                          ceci dis je pensais si je fais une fonction deplacer dans ma classe mere et que j'en refais une dans la classe fille je dois aussi faire ce truc ?

                          1. void deplacer(int orientation) : Pnj(orientation)


                          (exemple vite fais

                          merci encore pour vos réponse


                          Non, tu ne doit appeler que le constructeur de ta classe mère que lorsque le constructeur de ta classe fille est appeler. Ton objet est déjà créer pourquoi réappeler le constructeur?
                          • Partager sur Facebook
                          • Partager sur Twitter
                            8 août 2007 à 22:58:31

                            Non si tu fait sa sa veut dire que ta fonction déplacer va appeller le constructeur de la classe mère avec comme paramètre (orientation) ce n'est pas l'objectif il me semble par contre tu doit déclarer la fonction de la classe mère qui à le même nom virtual, comme je l'ai fait plus au pour ton destructeur. Ce mot permet au langage de savoir quel fonction appelle selon que l'objet est de la classe mère ou de la classe fille.

                            Comme tes 2 fonction ont le même nom et qu'une classe hérite de l'autre elle va se retrouver avec 2 fonction de même nom, et de même paramètre si j'ai bien compris, donc même signature, le programme ne saura pas qu'elle est la bonne fonction à appellé, si le mot clé virtuelle est présent, si l'objet est de classe mère c'est la fonction de la classe mère qui est appellé et pareil pour la classe fille. D'ou l'utilité de déclarer la fonction de la classe mère virtuel.

                            Fait le avec les destructeurs de tes classes mère aussi.
                            • Partager sur Facebook
                            • Partager sur Twitter
                            FaQ : Fr | En 1 2 | C++11 | Template || Blog : Deloget | C++|Boost--Dev | C++Next | GotW || Installer Boost
                              8 août 2007 à 23:12:58

                              Citation : icare14

                              Citation : lmghs

                              Il peut y avoir 150 constructeurs différents, mais il n'y a qu'un seul destructeur.Dans tous les cas, le chainage est obligatoire. Implicite pour le destructeur. Implicite vers le constructeur par défaut si rien n'est précisé ; explicite si précisé.



                              pardonne mon inculture mais le tutorial que j'ai trouvé parle pas de chainage ^^ c'est quoi en fait ?



                              Je crois que ce que lmghs veut dire par la c'est que : si un constructeur d'une classe dérivée prend des paramètres, on doit IMPERATIVEMENT EXPLICITER le constructeur de la classe de base que l'on veut utiliser. Dans les autres cas, ce chainage des constructeurs est fait implicitement par le compilateur avec les constructeurs par défaut. Arrêtez-moi si je me trompe, c'est nouveau pour moi aussi :-°
                              • Partager sur Facebook
                              • Partager sur Twitter
                              Inkamath on GitHub - Interpréteur d'expressions mathématiques. Reprise du développement en cours.
                                8 août 2007 à 23:48:14

                                Le chainage, c'est le fait qu'un constructeur (/resp. destructeur) appelle _un_ constructeur (/resp. _le_ destructeur) de la classe parente.

                                Dans le cas des constructeur, par défaut, c'est le constructeut par défaut (des classes parentes) qui est appellé car rien n'est explicité. En explicitant, on choisit son constructeur. C'est tout ce que je voulais dire.

                                (Il est évident qu'avec une classe mère sans constructeur par défaut (comme ici), il faut obligatoirement expliciter le constructeur parent que l'on veut)

                                (je vous passe les cas particuliers des héritages multiples, virtuels ou non)


                                Et, NON, ce n'est pas delete[] qui doit être appelé ici!
                                • 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.
                                  8 août 2007 à 23:54:15

                                  Citation : lmghs


                                  Et, NON, ce n'est pas delete[] qui doit être appelé ici!


                                  Ici non, mais c'est quand même delete[] qui faut utiliser et non la méthode de atoboldom.
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    9 août 2007 à 0:52:56

                                    Non. La méthode d'atoboldom est celle qui doit être employée avec les tableaux statiques de pointeurs -- ce qui ce trouve être ce qu'utilise l'OP. Il ne faut pas la rejeter parce qu'ailleurs on a juste des tableaux de variables. Ce sont deux choses différentes.
                                    • 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.
                                      9 août 2007 à 2:15:02

                                      Citation : lmghs

                                      Non. La méthode d'atoboldom est celle qui doit être employée avec les tableaux statiques de pointeurs -- ce qui ce trouve être ce qu'utilise l'OP. Il ne faut pas la rejeter parce qu'ailleurs on a juste des tableaux de variables. Ce sont deux choses différentes.


                                      Je voit ce que tu veux dire.
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        9 août 2007 à 3:12:40

                                        Mais en même temps ma méthode est fausse dans le cas présent ?
                                        Parceque c'est SDL_FreeSurface qui'il faut appeler non ?
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          9 août 2007 à 3:30:50

                                          Citation : atoboldom

                                          Mais en même temps ma méthode est fausse dans le cas présent ?
                                          Parceque c'est SDL_FreeSurface qui'il faut appeler non ?


                                          Si si, mais dans le cas contraire si ça n'aurais pas été des SDL_surface, ta méthode aurait été la bonne.
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            9 août 2007 à 10:36:23

                                            si j'ai bien compris comme mon tableau est un tableau de pointeur non-variable (au niveau de la taille) je détruit chaque pointeur de ce tableau un par un

                                            tandis que si c'était un simple tableau de valeur je pourrais utiliser delete[]

                                            c'est bien ça ?

                                            EDIT : une autre question : pour l'instant mon programme ne fait que déplacer un personnage à travers plusieurs niveau mais lorsque je fais ctrl + alt + delete je vois mon programme qui bouffe une mémoire pas possible (après deux minutes de déplacement jusqu'à 500 mo o_O ) je sais pas trop d'ou ça vient mais est ce que c'est possible que ça vienne du fait que j'ai créé une fonction qui blitte les image en les appellant puis en les détruisant

                                            (ça serait plus clair avec le code ^^ )
                                            1. void blitterimage(SDL_Surface *ecran, int plateau[][NBR_CASE_HAUTEUR])
                                            2. {
                                            3.     SDL_Surface *maison = NULL, *chateau = NULL, *arbre = NULL, *fond = NULL;
                                            4.     SDL_Rect posobjet;
                                            5.     fond = IMG_Load("image/environnement/fond_herbe.bmp");//image de fond
                                            6.     maison = IMG_Load("image/environnement/maison_chem.bmp");//maison avec cheminee
                                            7.     SDL_SetColorKey(maison, SDL_SRCCOLORKEY, SDL_MapRGB(maison->format, 255, 0, 0));//transparence
                                            8.     chateau = IMG_Load("image/environnement/chateau.bmp");
                                            9.     SDL_SetColorKey(chateau, SDL_SRCCOLORKEY, SDL_MapRGB(chateau->format, 0, 128, 0));//transparence
                                            10.     arbre = IMG_Load("image/environnement/arbre.bmp");
                                            11.     SDL_SetColorKey(arbre, SDL_SRCCOLORKEY, SDL_MapRGB(chateau->format, 0, 0, 255));
                                            12.     SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255)); /* On efface l'écran */
                                            13.     posobjet.x= 0;
                                            14.     posobjet.y = 0;
                                            15.     SDL_BlitSurface(fond, NULL, ecran, &posobjet);//on colle le fond
                                            16.     for(int i = 0; i < NBR_CASE_HAUTEUR; i++)//pour tout x
                                            17.               {
                                            18.               for(int j = 0; j < NBR_CASE_LARGEUR; j++)//pour tout Y
                                            19.                     {
                                            20.                     switch(plateau[j][i])//on compare le tableau
                                            21.                           {
                                            22.                           case VIDE:
                                            23.                                break;
                                            24.                           case MAISON:
                                            25.                                posobjet.x = LARGEUR * j;
                                            26.                                posobjet.y = HAUTEUR * i;
                                            27.                                SDL_BlitSurface(maison, NULL, ecran, &posobjet);
                                            28.                                break;
                                            29.                           case CHATEAU:
                                            30.                                posobjet.x = LARGEUR * j;
                                            31.                                posobjet.y = HAUTEUR * i;
                                            32.                                SDL_BlitSurface(chateau, NULL, ecran, &posobjet);
                                            33.                                break;
                                            34.                           case ARBRE:
                                            35.                                posobjet.x = LARGEUR * j;
                                            36.                                posobjet.y = HAUTEUR * i;
                                            37.                                SDL_BlitSurface(arbre, NULL, ecran, &posobjet);
                                            38.                                break;
                                            39.                           }
                                            40.                     }
                                            41.               }
                                            42.     SDL_FreeSurface(chateau);
                                            43.     SDL_FreeSurface(maison);
                                            44.     SDL_FreeSurface(arbre);
                                            45. }


                                            et voici comment j'utilise cette fonction :

                                            1. ...    
                                            2. blitterimage(ecran,plateau);//on préblitte toutes les images pour le décors
                                            3.     Prophete.deplacer(ecran, BAS, plateau_collision, plateau);
                                            4.     SDL_Flip(ecran);
                                            5.     while (continuer)//boucle evenementielle
                                            6.     {
                                            7.         SDL_WaitEvent(&event);
                                            8.         switch(event.type)
                                            9.         {
                                            10.             case SDL_QUIT:
                                            11.                 continuer = 0;
                                            12.                 break;
                                            13.             case SDL_KEYDOWN:
                                            14.                 switch(event.key.keysym.sym)
                                            15.                 {
                                            16.                     case SDLK_UP: // Flèche haut
                                            17.                         blitterimage(ecran, plateau);
                                            18.                         Prophete.deplacer(ecran, HAUT, plateau_collision, plateau);
                                            19.                         break;
                                            20.                     case SDLK_DOWN: // Flèche bas
                                            21.                         blitterimage(ecran,plateau);
                                            22.                         Prophete.deplacer(ecran, BAS, plateau_collision, plateau);
                                            23.                         break;
                                            24.                     case SDLK_RIGHT: // Flèche droite
                                            25.                         blitterimage(ecran,plateau);
                                            26.                         Prophete.deplacer(ecran, DROITE, plateau_collision, plateau);
                                            27.                         break;
                                            28.                     case SDLK_LEFT: // Flèche gauche
                                            29.                         blitterimage(ecran,plateau);
                                            30.                         Prophete.deplacer(ecran, GAUCHE, plateau_collision, plateau);
                                            31.                         break;
                                            32.                     case SDLK_ESCAPE:
                                            33.                          continuer = 0;
                                            34.                          break;
                                            35.                 }
                                            36.                 break;
                                            37.         }
                                            38.         SDL_Flip(ecran); /* On met à jour l'affichage */
                                            39.     }
                                            40. ...


                                            P.S : si vous voulez autre chose demandez moi

                                            merci encore
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              9 août 2007 à 11:26:36

                                              Evite de faire des chargements d'images a chaque tour de ta boucle principale.. Il faut faire tous les chargements en une seul fois au début du programme... :)

                                              Ensuite si tu as toujours un problème, vérifie que tu n'as pas de fuite de mémoire.
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                              Inkamath on GitHub - Interpréteur d'expressions mathématiques. Reprise du développement en cours.
                                                9 août 2007 à 12:30:47

                                                merci inakoll ça marche
                                                • Partager sur Facebook
                                                • Partager sur Twitter

                                                héritage

                                                × 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