Partage
  • Partager sur Facebook
  • Partager sur Twitter

error: definition of implicitly-declared

Sujet résolu
    27 mars 2020 à 20:47:37

    J'ai un petit problème, je veux créer un "operator=" de ma classe Personnage, j'ai cherché et j'ai vu que il fallait le déclarer dans le .h mais il sort quand même une erreur, voici mon Personnage.cpp et mon Personnage.h :

    Personnage.cpp :

    #include "Personnage.h"
    #include <iostream>
    
    //Constructeur
    //Bla-Bla-Bla
    
    
    //Operateur
    Personnage& Personnage::operator=(Personnage const& personnageACopier) //Quand on fait david = gontran
    {
        if (this != &personnageACopier) //On verifie qu'on fait pas gontran = gontran
        {
            m_vie = personnageACopier.m_vie;
            m_mana = personnageACopier.m_mana;
            delete m_arme; //On supprime le lien entre le nouveau personnage et l'adresse de l'arme du gars qu'on copiess
            m_arme = new Arme(*(personnageACopier.m_arme));
        }
        return *this;
        
    }
    


    Personnage.h :

    #ifndef DEF_PERSONNAGE
    #define DEF_PERSONNAGE
     
    #include <iostream>
    #include <string>
    #include "Arme.cpp"
     
    class Personnage
    {
        public:
            Personnage();
            Personnage(string nomArme, int degatsArme);
            Personnage(Personnage const& personnageACopier);
            void recevoirDegats(int degats);
            void coupDePoing(Personnage &cible) const;
            ~Personnage();
     
        private:
            int m_vie;
            int m_mana;
            Arme *m_arme;
    };
    
    #endif

    Voila, j'ai enlevé la déclaration dans Personage.h mais quand je la mettais je me retrouvais avec la même erreur

    J'ai besoin d'aide s'il vous plaait :(

    • Partager sur Facebook
    • Partager sur Twitter
      27 mars 2020 à 21:09:54

      N'inclus pas Arme.cpp dans Personnage.h

      D'une maniere generale, n'inclus jamais un .cpp dans d'autres fichiers.

      -
      Edité par SpaceIn 27 mars 2020 à 21:10:42

      • Partager sur Facebook
      • Partager sur Twitter
        27 mars 2020 à 21:23:58

        Bonjour,

        Une chose sûre : on ne peut pas définir une fonction membre si on ne l'a pas déclarée dans la classe. Il faut donc y remettre la déclaration.

        Une chose inquiétante : ton fichier header inclut un fichier cpp. Ça ne doit jamais être effectué, et c'est peut-être la cause de ton problème.

        Connais-tu la règle des 3, la règle des 5 et la règle du zéro? C'est en gros une seule et même règle qui dit : Ne jamais jamais jamais gérer soit même les allocations (donc pas de new ni de delete). Seul un expert pourrais le faire, et un expert maîtrise forcément la règle des 5.
        Je suis loin d'être un expert - ça ne fait que trente ans que je pratique le C++ - mais redéfinir l'opérateur d'affectation sans redéfinir le constructeur de copie, je n'ai jamais vu cela.

        D'autre part, il y a un bug dans ton opérateur de copie. Il manque entre la ligne 15 et la ligne 16 : m_arme = nullptr; 

        • Partager sur Facebook
        • Partager sur Twitter

        En recherche d'emploi.

          27 mars 2020 à 21:52:28

          SpaceIn a écrit:

          N'inclus pas Arme.cpp dans Personnage.h

          D'une maniere generale, n'inclus jamais un .cpp dans d'autres fichiers.


          Oui mais sans ça il me génère une autre erreur qui là empêche tout fonctionnement alors quand mettant le cpp tout fonctionnait.

          Resultat :

          C:\Users\Moi\AppData\Local\Temp\ccRqNmRv.o: In function `main':
          c:/TP/Heritage/main.cpp:8: undefined reference to `Personnage::Personnage(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)'
          c:/TP/Heritage/main.cpp:10: undefined reference to `Personnage::Personnage(Personnage const&)'
          c:/TP/Heritage/main.cpp:13: undefined reference to `Personnage::Personnage()'
          c:/TP/Heritage/main.cpp:15: undefined reference to `Personnage::coupDePoing(Personnage&) const'
          c:/TP/Heritage/main.cpp:13: undefined reference to `Personnage::~Personnage()'
          c:/TP/Heritage/main.cpp:10: undefined reference to `Personnage::~Personnage()'
          c:/TP/Heritage/main.cpp:8: undefined reference to `Personnage::~Personnage()'
          c:/TP/Heritage/main.cpp:13: undefined reference to `Personnage::~Personnage()'
          c:/TP/Heritage/main.cpp:10: undefined reference to `Personnage::~Personnage()'
          C:\Users\Moi\AppData\Local\Temp\ccRqNmRv.o:c:/TP/Heritage/main.cpp:8: more undefined references to `Personnage::~Personnage()' follow
          collect2.exe: error: ld returned 1 exit status
          The terminal process terminated with exit code: 1



          Dalfab a écrit:

          Connais-tu la règle des 3, la règle des 5 et la règle du zéro? C'est en gros une seule et même règle qui dit : Ne jamais jamais jamais gérer soit même les allocations (donc pas de new ni de delete). Seul un expert pourrais le faire, et un expert maîtrise forcément la règle des 5.

          Je suis un cours qui nous demande de les utiliser, moi je suis juste le cours et il ne parle pas "des règles 0, 3, 5 ?"

          • Partager sur Facebook
          • Partager sur Twitter
            27 mars 2020 à 21:55:52

            C'est normal, c'est Arme.h qu'il faut inclure, à la place de Arme.cpp
            • Partager sur Facebook
            • Partager sur Twitter
              27 mars 2020 à 21:58:37

              C'est après avoir mit Arme.h qu'il me sort cette erreur.
              • Partager sur Facebook
              • Partager sur Twitter
                27 mars 2020 à 22:43:08

                Montre tous tes fichiers, ce sera plus simple pour nous.
                • Partager sur Facebook
                • Partager sur Twitter
                  27 mars 2020 à 23:27:26

                  En c++, la compilation passe essentiellement par 2 phases:

                  • La compilation d'un .cpp en .o
                  • Le regroupement de tous les .o en un exécutable

                  Les erreurs de référence indéfinie sont dues à la seconde phase: les fonctions ne sont trouvées dans aucun .o. Ce qui veut dire soit que Personnage.cpp n'est pas compilé, soit que certaines fonctions ne sont pas implémentées.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    28 mars 2020 à 13:17:59

                    SpaceIn a écrit:

                    Montre tous tes fichiers, ce sera plus simple pour nous.


                    Main.cpp

                    #include "Personnage.h"
                    #include <string>
                    
                    using namespace std;
                    
                    int main()
                    {
                        Personnage goliath("Epée aiguisée", 20);
                        
                        Personnage david(goliath);
                        //On crée david à partir de goliath. david sera une « copie » de goliath.
                    
                        Personnage gontran;
                        gontran = david;
                        gontran.coupDePoing(goliath);
                    
                        return 0;
                    }

                    Personnage.cpp

                    #include "Personnage.h"
                    #include <iostream>
                    
                    Personnage::Personnage() : m_vie(100), m_mana(100), m_arme(0)
                    {
                        m_arme = new Arme();
                    }
                    
                    Personnage::Personnage(string nomArme, int degatsArme) : m_vie(100), m_mana(100), m_arme(0)
                    {
                        m_arme = new Arme(nomArme, degatsArme);
                    }
                    
                    Personnage::Personnage(Personnage const& personnageACopier)
                        : m_vie(personnageACopier.m_vie), m_mana(personnageACopier.m_mana), m_arme(0)
                    {
                        m_arme = new Arme(*(personnageACopier.m_arme));
                    }
                    
                    
                    
                    
                    void Personnage::recevoirDegats(int degats)
                    {
                        m_vie -= degats;
                        cout << m_vie << endl;
                    }
                    
                    void Personnage::coupDePoing(Personnage &cible) const
                    {
                        cible.recevoirDegats(m_arme->getDegats());
                    }
                    
                    Personnage& Personnage::operator=(Personnage const& personnageACopier) //Quand on fait david = gontran
                    {
                        if (this != &personnageACopier) //On verifie qu'on fait pas gontran = gontran
                        {
                            m_vie = personnageACopier.m_vie;
                            m_mana = personnageACopier.m_mana;
                            delete m_arme; //On supprime le lien entre le nouveau personnage et l'adresse de l'arme du gars qu'on copiess
                            m_arme = new Arme(*(personnageACopier.m_arme));
                        }
                        return *this;
                        
                    }
                    
                    
                    Personnage::~Personnage()
                    {
                        delete m_arme;
                    }

                    Personnage.h

                    #ifndef DEF_PERSONNAGE
                    #define DEF_PERSONNAGE
                     
                    #include <iostream>
                    #include <string>
                    #include "Arme.h"
                     
                    class Personnage
                    {
                        public:
                            Personnage();
                            Personnage(std::string nomArme, int degatsArme);
                            Personnage(Personnage const& personnageACopier);
                            void recevoirDegats(int degats);
                            void coupDePoing(Personnage &cible) const;
                            ~Personnage();
                     
                        private:
                            int m_vie;
                            int m_mana;
                            Arme *m_arme;
                    };
                    
                    
                    
                    #endif

                    Arme.cpp

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

                    Arme.h

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

                    jo_link_noir a écrit:

                    En c++, la compilation passe essentiellement par 2 phases:

                    • La compilation d'un .cpp en .o
                    • Le regroupement de tous les .o en un exécutable

                    Les erreurs de référence indéfinie sont dues à la seconde phase: les fonctions ne sont trouvées dans aucun .o. Ce qui veut dire soit que Personnage.cpp n'est pas compilé, soit que certaines fonctions ne sont pas implémentées.


                    C'était d'ailleurs pour ça que j'avais include les .cpp

                    -
                    Edité par Elowarp 28 mars 2020 à 13:35:48

                    • Partager sur Facebook
                    • Partager sur Twitter
                      30 mars 2020 à 11:28:56

                      Personnage.cpp n'est pas dans la liste des fichiers à compiler, corrigez cela dans votre IDE.
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                        30 mars 2020 à 11:33:53

                        NoWeLPTDR a écrit:

                        Oui mais sans ça il me génère une autre erreur qui là empêche tout fonctionnement alors quand mettant le cpp tout fonctionnait.

                        C'est pas une raison pour faire n'importe quoi.

                        Les erreurs, elles ont des causes. Il faut les rechercher, et comprendre, et rectifier correctement. Sinon, tant qu'on n'a pas compris, elles se reproduisent constamment. Sales betes.

                        -
                        Edité par michelbillaud 30 mars 2020 à 11:34:40

                        • Partager sur Facebook
                        • Partager sur Twitter
                          30 mars 2020 à 23:20:26

                          michelbillaud a écrit:

                          C'est pas une raison pour faire n'importe quoi.

                          Les erreurs, elles ont des causes. Il faut les rechercher, et comprendre, et rectifier correctement. Sinon, tant qu'on n'a pas compris, elles se reproduisent constamment. Sales betes.

                          Oui mais je pensais que c'était comme ça car l'erreur était partie et tout fonctionnait :(

                          • Partager sur Facebook
                          • Partager sur Twitter
                            31 mars 2020 à 9:50:30

                            Par contre ton code fait parti des classiques erreur de débutants. Un personnage a une sémantique d'entité, il n'est pas censé être copiable car il est unique.

                            Et d'ailleurs la copie d'arme est aussi à perte car faire une copie polymorphique n'est pas aussi simple que ça (d'où le fait de ne pas copier).

                            • Partager sur Facebook
                            • Partager sur Twitter

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

                              1 avril 2020 à 0:53:20

                              Je sais qu'il fait parti des erreurs de débutant car j'en suis un. Je suis même pas encore à la moitié du cours d'OCR (au moment où on essaye de copier justement) bref je suis toujours un peu bloqué jusque ici :/
                              • Partager sur Facebook
                              • Partager sur Twitter
                                1 avril 2020 à 13:32:01

                                Comme dit precedemment plusieurs fois, un de tes fichiers cpp n'est probablement pas compilé. Verifie dans ton systeme de build (celui de Code Blocks?) que tous les fichiers .cpp sont bien listés.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  1 avril 2020 à 20:06:37

                                  D'accord j'ai inclut tous les .cpp dans ma commande g++ et ça a marché ^^' 

                                  Désolé de vous avoir dérangé, merci beaucoup.

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    2 avril 2020 à 8:48:00

                                    NoWeLPTDR a écrit:

                                    D'accord j'ai inclut tous les .cpp dans ma commande g++ et ça a marché ^^' 

                                    Désolé de vous avoir dérangé, merci beaucoup.


                                    Ce n'est pas la manière de faire. C'est ok pour des petits programmes mais lorsqu'on travaille avec une application ayant des milliers de fichiers on utilise un vrai système de build (CMake ou Make au minimum).
                                    • Partager sur Facebook
                                    • Partager sur Twitter

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

                                      2 avril 2020 à 23:14:19

                                      markand a écrit:

                                      NoWeLPTDR a écrit:

                                      D'accord j'ai inclut tous les .cpp dans ma commande g++ et ça a marché ^^' 

                                      Désolé de vous avoir dérangé, merci beaucoup.


                                      Ce n'est pas la manière de faire. C'est ok pour des petits programmes mais lorsqu'on travaille avec une application ayant des milliers de fichiers on utilise un vrai système de build (CMake ou Make au minimum).

                                      Je ne sais pas comment faire un vrai système de build avec CMake ou Make mais bon pour l'instant ça me suffit grandement pour mon cours.
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        3 avril 2020 à 0:24:50

                                        Et bien avec CMake ce serait ultra simple.

                                        En supposant que tu découpes ton projet qu'on appellerait "LearnCpp" en un sous-répertoire par exercice, tu pourrais écrire un fichier CMakeLists.txt à la racine du projet comme ceci:

                                        cmake_minimum_required(VERSION 2.8)
                                        
                                        project(LearnCpp)
                                        
                                        # Exercise 1
                                        add_executable(exo01
                                          exercise01/main.cpp
                                          exercise01/Personnage.cpp
                                          exercise01/Arme.cpp
                                        )
                                        

                                        Si ton IDE a une intégration de CMake, tu voudras surement ajouter les fichiers header dans le add_executable, pour que le linter et l'autocomplétion s'y retrouvent, mais en soit pour la compilation ça n'a pas d'importance.

                                        Si tu fais un nouvel exercice, hop un nouveau répertoire "exercise02" et tu ajoutes dans le même fichier CMakeLists.txt un add_executable.

                                        En théorie, si tu apprends le C++ avec un cours sérieux, tu vas te retrouver avec des centaines d'exercices (C++ Primer doit en avoir pas loin d'un millier je crois). Donc un bon système de build te permet de bien décrire tout ce bazar en un ou plusieurs fichiers très clairs, et revenir plus tard sur un vieil exercice facilement (et même avec un autre compilateur ou OS).

                                        De toute façon, à un moment donné tu sentiras bien qu'il faut ajouter une couche d'abstraction à ton build pour te simplifier la vie.

                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        error: definition of implicitly-declared

                                        × 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