Partage
  • Partager sur Facebook
  • Partager sur Twitter

Erreur difficilement trouvable

Affichage non-voulu en console d'un programme en POO

Sujet résolu
    14 juin 2023 à 19:34:22

    Bonjour

    je souhaiterai faire afficher en console le texte comme dans le cours dédié à la POO d'open classrooms :

    Je dispose pour cela des fichiers suivant :

    fichier Arme.cpp :

    #include "Arme.h"
    
    using namespace std;
    
    Arme::Arme() : m_nom("Epee rouillee"), m_degats(10)
    {
    
    }
    
    Arme::Arme(string nom, int degats) : m_nom(nom), m_degats(degats)
    {
    
    }
    
    void Arme::changer(string nom, int degats)
    {
        m_nom = nom;
        m_degats = degats;
    }
    
    void Arme::afficher() const
    {
        cout << "Arme : " << m_nom << " (Degats : " << m_degats << ")" << endl;
    }
    

    fichier main.cpp :

    #include <iostream>
    #include "Personnage.h" //Ne pas oublier
    #include "Arme.h"
    
    using namespace std;
    
    //dans ce projet on a adapté la classe Personnage pour utiliser la classe Arme
    int main()
    {
        //Création des personnages
        Personnage david, goliath("Epee aiguisee", 20);
    
        //Au combat !
        goliath.attaquer(david);
        david.boirePotionDeVie(20);
        goliath.attaquer(david);
        david.attaquer(goliath);
        goliath.changerArme("Double hache tranchante veneneuse de la mort", 40);
        goliath.attaquer(david);
    
        //Temps mort ! Voyons voir la vie de chacun…
        cout << "David" << endl;
        david.afficherEtat();
        cout << endl << "Goliath" << endl;
        goliath.afficherEtat();
    
        return 0;
    }
    

    fichier Personnage.cpp :

    #include "Personnage.h"
    #include "Arme.h"
    
    using namespace std;//on a le droit de l'écrire ici car ce n'est pas le fichier.h
    
    ////constructeur
    //Personnage::Personnage()
    //{
    //    m_vie = 100;
    //    m_mana = 100;
    //    m_nomArme = "Epee rouillee";
    //    m_degatsArme = 10;
    //}
    
    //le constructeur ci-dessus peut aussi s'écrire:
    Personnage::Personnage() : m_vie(100), m_mana(100), m_arme("Epee rouillee", 10)
    {
        //Rien à mettre dans le corps du constructeur, tout a déjà été fait !
    }
    
    //pour la surcharge du constructeur (c'est-à-dire construire plusieurs constructeurs)
    Personnage::Personnage(string nomArme, int degatsArme) : m_vie(100), m_mana(100), m_arme(nomArme, degatsArme)
    {
    
    }
    
    void Personnage::recevoirDegats(int nbDegats)
    {
        m_vie =- nbDegats;//On enlève le nombre de dégâts reçus à la vie du personnage
    
        if(m_vie < 0)//Pour éviter d'avoir une vie négative
        {
            m_vie = 0;//On met la vie à 0 (cela veut dire mort)
        }
    }
    
    void Personnage::afficherEtat()
    {
        cout << "vie : " << m_vie << endl;
        cout << "mana : " << m_mana << endl;
        m_arme.afficher();
    
        //on remplace par la méthode afficher de l'arme
        //cout << "nom de l'arme : " << m_nomArme << endl;
        //cout << "degat de l'arme : " << m_degatsArme << endl;
    }
    
    ////exemple de si on veut changer le comportement du constructeur de copie
    //Personnage::Personnage(Personnage const& autre): m_vie(autre.m_vie), m_mana(autre.m_mana), m_nomArme(autre.m_nomArme), m_degatsArme(autre.m_degatsArme)
    //{
    //}
    
    void Personnage::attaquer(Personnage &cible)
    {
        cible.recevoirDegats(m_degatsArme);//On inflige à la cible les dégâts que
                                           //cause notre arme
    }
    
    void Personnage::boirePotionDeVie(int quantitePotion)
    {
        m_vie += quantitePotion;
        if(m_vie > 100)
        {
            m_vie = 100;
        }
    }
    
    void Personnage::changerArme(string nomNouvelleArme, int degatsNouvelleArme)
    {
        m_nomArme = nomNouvelleArme;
        m_degatsArme = degatsNouvelleArme;
    }
    
    bool Personnage::estVivant()
    {
        return m_vie > 0;
    }
    

    fichier Arme.h :

    #ifndef ARME_H_INCLUDED
    #define ARME_H_INCLUDED
    
    #include <iostream>
    #include <string>
    
    class Arme
    {
        public:
    
        Arme();
        Arme(std::string nom, int degats);
        void changer(std::string nom, int degats);
        void afficher() const;
    
        private:
    
        std::string m_nom;
        int m_degats;
    };
    
    #endif // ARME_H_INCLUDED
    

    fichier Personnage.h :

    #ifndef PERSONNAGE_H_INCLUDED
    #define PERSONNAGE_H_INCLUDED
    
    #include "Arme.h"
    
    class Personnage
    {
        public:
            Personnage(); //Constructeur
            Personnage(std::string nomArme, int degatsArme);
            void recevoirDegats(int nbDegats);
            void afficherEtat();
            void attaquer(Personnage &cible);
            void boirePotionDeVie(int quantitePotion);
            void changerArme(std::string nomNouvelleArme, int degatsNouvelleArme);
            bool estVivant();
    
        private:
            int m_vie;
            int m_mana;
            std::string m_nomArme;
            int m_degatsArme;
            Arme m_arme;
    };
    
    #endif // PERSONNAGE_H_INCLUDED
    

    Le problème est qu'apparemment j'ai une ou des erreurs dans mes programmes qui l'empêche de calculer le niveau de vie correctement en le maintenant à 0, et que j'ai du mal à repérer :

    Quelqu'un aurait-il une idée de la raison du coincement dans le programme ?

    Cordialement

    -
    Edité par 1Stark 14 juin 2023 à 23:06:55

    • Partager sur Facebook
    • Partager sur Twitter
      14 juin 2023 à 21:53:38

      Bonjour,

      Tes personnages sont curieusement équipés. Ils ont une m_arme capable d'infliger m_degat. Mais au moment des attaques, on utilise un autre champ appelé m_DegatsArme qui n'est jamais initialisé. Donc chaque attaque inflige un nombre inconnu de dégâts qui ôte à l'arrivée plus que les 100 points de vie initiaux.

      Les champs m_nomArme et m_degatsArme sont de trop!

      • Partager sur Facebook
      • Partager sur Twitter

      En recherche d'emploi.

        14 juin 2023 à 22:02:46

        @1Stark Revenir éditer ton message pour tout supprimer une fois que tu es reçu une réponse c'est pas cool. En plus de faire un post fantôme, avec juste une réponse à une question mystère, tu empêches tous ceux qui pourraient avoir le même problème que toi de trouver ton post et la réponse qui va avec

        C'est pas une bonne pratique sur un forum d'entraide

        • Partager sur Facebook
        • Partager sur Twitter
          15 juin 2023 à 8:05:30

          Ptite question annexe, probablement stupide:

          Il y a un interet a mettre include iostream dans le h sachant qu'il n'est utilise que dans l'implementation, ca ne fait pas un couplage fort avec la techno de l'implementation?

          • Partager sur Facebook
          • Partager sur Twitter
            15 juin 2023 à 10:16:31

            Très bonne remarque @P.X.L, oui il faut éviter de mettre des données d'implémentation dans le .h.

            C'est l'une des plus grosses faiblesses du C++, je trouve, car des fois, on n'a pas le choix sans complexifier le bidule.

            Je sais pas si les modules règlent "correctement" ces problèmes.

            • Partager sur Facebook
            • Partager sur Twitter
            Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
              15 juin 2023 à 11:19:51

              Mon petit doigt me dit que tu es entrain de suivre le cours du C++ de ce site, je t'invite donc à suivre un vrai cours à jours plutôt que cette abomination.
              • Partager sur Facebook
              • Partager sur Twitter

              git is great because Linus did it, mercurial is better because he didn't.

                15 juin 2023 à 12:11:35

                Bonjour,

                Il y a un cours à jour sur www.zestedesavoir.com qui apprend à coder en C++ de manière moderne.

                • Partager sur Facebook
                • Partager sur Twitter

                Mon site web de jeux SDL2 entre autres : https://www.ant01.fr

                  15 juin 2023 à 15:47:31

                  Bonjour

                  Merci à tous les aideurs.

                  @Dalfab @rouIoude En supprimant m_nomArme et m_degatsArme, en inversant le "+" et le "-" indiqué, et en ajoutant la méthode "int avoirDesDegats() const;" implémentéé comme ceci :

                  int Arme::avoirDesDegats() const//méthode ajoutée implémentée
                      return m_degats;
                  }

                  Le code se met à fonctionner comme voulu :

                  fichier Arme.cpp :

                  #include "Arme.h"
                  
                  using namespace std;
                  
                  Arme::Arme() : m_nom("Epee rouillee"), m_degats(10)
                  {
                  
                  }
                  
                  Arme::Arme(string nom, int degats) : m_nom(nom), m_degats(degats)
                  {
                  
                  }
                  
                  void Arme::changer(string nom, int degats)
                  {
                      m_nom = nom;
                      m_degats = degats;
                  }
                  
                  void Arme::afficher() const
                  {
                      cout << "Arme : " << m_nom << " (Degats : " << m_degats << ")" << endl;
                  }
                  
                  int Arme::avoirDesDegats(){ const//méthode ajoutée implémentée
                      return m_degats;
                  }
                  
                  

                  fichier main.cpp :

                  #include <iostream>
                  #include "Personnage.h" //Ne pas oublier
                  #include "Arme.h"
                  
                  using namespace std;
                  
                  //dans ce projet on a adapté la classe Personnage pour utiliser la classe Arme
                  int main()
                  {
                      //Création des personnages
                      Personnage david, goliath("Epee aiguisee", 20);
                  
                      //Au combat !
                      goliath.attaquer(david);
                      david.boirePotionDeVie(20);
                      goliath.attaquer(david);
                      david.attaquer(goliath);
                      goliath.changerArme("Double hache tranchante veneneuse de la mort", 40);
                      goliath.attaquer(david);
                  
                      //Temps mort ! Voyons voir la vie de chacun…
                      cout << "David" << endl;
                      david.afficherEtat();
                      cout << endl << "Goliath" << endl;
                      goliath.afficherEtat();
                  
                      return 0;
                  }
                  

                  fichier Personnage.cpp :

                  #include "Personnage.h"
                  #include "Arme.h"
                  
                  using namespace std;//on a le droit de l'écrire ici car ce n'est pas le fichier.h
                  
                  ////constructeur
                  //Personnage::Personnage()
                  //{
                  //    m_vie = 100;
                  //    m_mana = 100;
                  //    m_nomArme = "Epee rouillee";
                  //    m_degatsArme = 10;
                  //}
                  
                  ////le constructeur ci-dessus peut aussi s'écrire:
                  //Personnage::Personnage() : m_vie(100), m_mana(100), m_arme("Epee rouillee", 10)
                  //{
                  //    //Rien à mettre dans le corps du constructeur, tout a déjà été fait !
                  //}
                  
                  Personnage::Personnage() : m_vie(100), m_mana(100)
                  {
                      //Rien à mettre dans le corps du constructeur, tout a déjà été fait !
                  }
                  
                  //pour la surcharge du constructeur (c'est-à-dire construire plusieurs constructeurs)
                  Personnage::Personnage(string nomArme, int degatsArme) : m_vie(100), m_mana(100), m_arme(nomArme, degatsArme)
                  {
                  
                  }
                  
                  ////destructeur probablement inutile ici
                  Personnage::~Personnage()
                  {
                  
                  }
                  
                  void Personnage::recevoirDegats(int nbDegats)
                  {
                      m_vie -= nbDegats;//Le moins et le égal étaient visiblement inversés
                  
                      if(m_vie < 0)//Pour éviter d'avoir une vie négative
                      {
                          m_vie = 0;//On met la vie à 0 (cela veut dire mort)
                      }
                  }
                  
                  void Personnage::attaquer(Personnage &cible)
                  {
                      cible.recevoirDegats(m_arme.avoirDesDegats());//m_degatsArme remplacé par
                                                                      //m_arme.avoirDesDegats()
                  
                  }
                  
                  void Personnage::boirePotionDeVie(int quantitePotion)
                  {
                      m_vie += quantitePotion;
                      if(m_vie > 100)
                      {
                          m_vie = 100;
                      }
                  }
                  
                  void Personnage::changerArme(string nomNouvelleArme, int degatsNouvelleArme)
                  {
                  //    m_nomArme = nomNouvelleArme;
                  //    m_degatsArme = degatsNouvelleArme;
                          m_arme.changer(nomNouvelleArme, degatsNouvelleArme);
                  }
                  
                  bool Personnage::estVivant()//peut-être à changer
                  {
                      return m_vie > 0;
                  }
                  
                  void Personnage::afficherEtat()
                  {
                      cout << "vie : " << m_vie << endl;
                      cout << "mana : " << m_mana << endl;
                      m_arme.afficher();
                  
                      //on remplace par la méthode afficher de l'arme
                      //cout << "nom de l'arme : " << m_nomArme << endl;
                      //cout << "degat de l'arme : " << m_degatsArme << endl;
                  }
                  
                  ////exemple de si on veut changer le comportement du constructeur de copie
                  //Personnage::Personnage(Personnage const& autre): m_vie(autre.m_vie), m_mana(autre.m_mana), m_nomArme(autre.m_nomArme), m_degatsArme(autre.m_degatsArme)
                  //{
                  //}
                  
                  

                  fichier Arme.h :

                  #include <iostream>
                  #include <string>
                  
                  class Arme
                  {
                      public:
                  
                      Arme();
                      Arme(std::string nom, int degats);
                      void changer(std::string nom, int degats);
                      void afficher() const;
                      int avoirDesDegats() const;//méthode ajoutée
                  
                      private:
                  
                      std::string m_nom;
                      int m_degats;
                  };
                  
                  #endif // ARME_H_INCLUDED
                  

                  fichier Personnage.h :

                  #ifndef PERSONNAGE_H_INCLUDED
                  #define PERSONNAGE_H_INCLUDED
                  
                  //#include <iostream>
                  //#include <string>
                  #include "Arme.h"
                  
                  class Personnage
                  {
                      public:
                          Personnage(); //Constructeur
                          Personnage(std::string nomArme, int degatsArme);
                          ~Personnage();//destructeur
                          void recevoirDegats(int nbDegats);
                          void attaquer(Personnage &cible);
                          void boirePotionDeVie(int quantitePotion);
                          void changerArme(std::string nomNouvelleArme, int degatsNouvelleArme);
                          bool estVivant();
                          void afficherEtat();
                  
                      private:
                          int m_vie;
                          int m_mana;
                  //        std::string m_nomArme;
                  //        int m_degatsArme;
                          Arme m_arme;
                  };
                  
                  #endif // PERSONNAGE_H_INCLUDED
                  

                  affichage en console :

                  @ThibaultVnt J'ai voulu modifié et réécrire complètement le post mais ayant été pressé, j'ai cliqué par erreur sur "envoyer" au lieu de "annuler" ce qui a provoqué un instant durant lequel le post est resté vide, le temps que je le réécrive sans savoir que quelqu'un m'avais répondu. Le post est à nouveau disponible et plus clair.

                  @P.X.L @bacelar De mon coté, aussitôt que j'enlève le "#include <iostream>" situé dans le fichier Arme.h, je ne peux plus lancer la console : 

                  @markand @Warren79 Cela fait plusieurs fois que l'on me fait la remarque : je devrais ouvrir un post concernant l'apprentissage. 


                  Cordialement




                  -
                  Edité par 1Stark 15 juin 2023 à 15:50:39

                  • Partager sur Facebook
                  • Partager sur Twitter
                    15 juin 2023 à 16:15:11

                    > @P.X.L @bacelar De mon coté, aussitôt que j'enlève le "#include <iostream>" situé dans le fichier Arme.h, je ne peux plus lancer la console :


                    Surtout ne lance pas la console, tu vas l’abîmer, et ça coûte cher à réparer.

                    Ce que tu fais en réalité, c'est que tu lances la compilation, qui fait parfaitement  son devoir en produisant le message qui signale que ton programme parle de cout qui est inconnu au bataillon. La console, elle affiche différents onglets, dont les "build messages" produits pendant la construction de l'exécutable.

                    Comme std::cout est déclaré dans iostream, il faut en effet placer un #include <iostream> quleque part.

                    Mais Arme.h, c'est pas le bon endroit. Tu en as besoin dans Arme.cpp  pour définir la fonction Arme::afficher (c'est à dire indiquer son code source, les instructions auxquelles elle correspond). Donc c'est en haut de Arme.cpp, que tu fois placer l'include.

                    Le fichier Arme.h sert à autre chose, déclarer quelles fonctions existent dans la classe Arme, avec quels paramètres. Mais pas comment elles sont programmées.

                    -
                    Edité par michelbillaud 15 juin 2023 à 17:21:10

                    • Partager sur Facebook
                    • Partager sur Twitter
                      15 juin 2023 à 16:58:51

                      avoirDesDegats  --> infligerDesDegats
                      • Partager sur Facebook
                      • Partager sur Twitter
                      ...
                        15 juin 2023 à 18:42:06

                        Bonsoir

                        Voici les nouveaux fichiers modifiés selon les remarques :

                        fichier Arme.cpp :

                        #include "Arme.h"
                        #include <iostream>
                        
                        using namespace std;
                        
                        Arme::Arme() : m_nom("Epee rouillee"), m_degats(10)
                        {
                        
                        }
                        
                        Arme::Arme(string nom, int degats) : m_nom(nom), m_degats(degats)
                        {
                        
                        }
                        
                        void Arme::changer(string nom, int degats)
                        {
                            m_nom = nom;
                            m_degats = degats;
                        }
                        
                        void Arme::afficher() const
                        {
                            cout << "Arme : " << m_nom << " (Degats : " << m_degats << ")" << endl;
                        }
                        
                        int Arme::infligerDesDegats() const//était manquant
                        {
                            return m_degats;
                        }

                        fichier Personnage.cpp :

                        #include "Personnage.h"
                        #include "Arme.h"
                        #include <iostream> //ajouté suite à l'erreur
                        
                        using namespace std;//on a le droit de l'écrire ici car ce n'est pas le fichier.h
                        
                        ////constructeur
                        //Personnage::Personnage()
                        //{
                        //    m_vie = 100;
                        //    m_mana = 100;
                        //    m_nomArme = "Epee rouillee";
                        //    m_degatsArme = 10;
                        //}
                        
                        ////le constructeur ci-dessus peut aussi s'écrire:
                        //Personnage::Personnage() : m_vie(100), m_mana(100), m_arme("Epee rouillee", 10)
                        //{
                        //    //Rien à mettre dans le corps du constructeur, tout a déjà été fait !
                        //}
                        
                        Personnage::Personnage() : m_vie(100), m_mana(100)
                        {
                            //Rien à mettre dans le corps du constructeur, tout a déjà été fait !
                        }
                        
                        //pour la surcharge du constructeur (c'est-à-dire construire plusieurs constructeurs)
                        Personnage::Personnage(string nomArme, int degatsArme) : m_vie(100), m_mana(100), m_arme(nomArme, degatsArme)
                        {
                        
                        }
                        
                        ////destructeur probablement inutile ici
                        Personnage::~Personnage()
                        {
                        
                        }
                        
                        void Personnage::recevoirDegats(int nbDegats)
                        {
                            m_vie -= nbDegats;//Le moins et le égal étaient visiblement inversés
                        
                            if(m_vie < 0)//Pour éviter d'avoir une vie négative
                            {
                                m_vie = 0;//On met la vie à 0 (cela veut dire mort)
                            }
                        }
                        
                        void Personnage::attaquer(Personnage &cible)
                        {
                            cible.recevoirDegats(m_arme.infligerDesDegats());//m_degatsArme remplacé par
                                                                            //m_arme.avoirDesDegats()
                        
                        }
                        
                        void Personnage::boirePotionDeVie(int quantitePotion)
                        {
                            m_vie += quantitePotion;
                            if(m_vie > 100)
                            {
                                m_vie = 100;
                            }
                        }
                        
                        void Personnage::changerArme(string nomNouvelleArme, int degatsNouvelleArme)
                        {
                        //    m_nomArme = nomNouvelleArme;
                        //    m_degatsArme = degatsNouvelleArme;
                                m_arme.changer(nomNouvelleArme, degatsNouvelleArme);
                        }
                        
                        bool Personnage::estVivant()//peut-être à changer
                        {
                            return m_vie > 0;
                        }
                        
                        void Personnage::afficherEtat()
                        {
                            cout << "vie : " << m_vie << endl;
                            cout << "mana : " << m_mana << endl;
                            m_arme.afficher();
                        
                            //on remplace par la méthode afficher de l'arme
                            //cout << "nom de l'arme : " << m_nomArme << endl;
                            //cout << "degat de l'arme : " << m_degatsArme << endl;
                        }
                        
                        ////exemple de si on veut changer le comportement du constructeur de copie
                        //Personnage::Personnage(Personnage const& autre): m_vie(autre.m_vie), m_mana(autre.m_mana), m_nomArme(autre.m_nomArme), m_degatsArme(autre.m_degatsArme)
                        //{
                        //}
                        

                        fichier Arme.h :

                        #ifndef ARME_H_INCLUDED
                        #define ARME_H_INCLUDED
                        
                        #include <string>
                        
                        class Arme
                        {
                            public:
                        
                            Arme();
                            Arme(std::string nom, int degats);
                            void changer(std::string nom, int degats);
                            void afficher() const;
                            int infligerDesDegats() const;//méthode ajoutée
                        
                            private:
                        
                            std::string m_nom;
                            int m_degats;
                        };
                        
                        #endif // ARME_H_INCLUDED

                        Comme après avoir déplacé l'"#include <iostream>" du fichier Arme.h vers le fichier Arme.cpp, une erreur était signalée, j'en ai ajouté un dans le fichier Personnage.cpp :

                        Cordialement

                        -
                        Edité par 1Stark 15 juin 2023 à 18:43:42

                        • Partager sur Facebook
                        • Partager sur Twitter
                          15 juin 2023 à 18:46:31

                          1Stark a écrit:

                          Comme après avoir déplacé l'"#include <iostream>" du fichier Arme.h vers le fichier Arme.cpp, une erreur était signalée, j'en ai ajouté un dans le fichier Personnage.cpp 

                          C'est ce qui fallait faire.

                          • Partager sur Facebook
                          • Partager sur Twitter
                          ...

                          Erreur difficilement trouvable

                          × 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