Partage
  • Partager sur Facebook
  • Partager sur Twitter

LNK2005: Problème de redéfinition

    8 février 2019 à 21:28:14

    Bonjour. J'ai le fichier Source.cpp suivant:
    #include "LGS.h"
    #include "Losangeles.h"
    
    
    int CALLBACK WinMain(
    	HINSTANCE hInstance,
    	HINSTANCE hPrevInstance,
    	LPSTR lpCmdLine,
    	int nCmdShow)
    {
    	Fen fen(500, 500, "salut");
    	
    
    
    	pause();
    	return 0;
    }

    Le fihier Losangeles suivant:

    #include "Matrice.h"
    #include "LGS.h"
    class Losangeles
    {
    public:
    	Losangeles();
    	~Losangeles();
    };
    

    Et le fichier LGS suivant:

    #pragma once
    #ifndef LGS_EST_DEF
    #define LGS_EST_DEF 1
    #include "Fen.cpp"
    #endif

    Quand j'essaie la compilation, le debbogeur renvoie pleins de lignes du type:

    1>Source.obj : error LNK2005: "public: __thiscall Fen::Fen(int,int,char const *,long)" (??0Fen@@QAE@HHPBDJ@Z) déjà défini(e) dans Losangeles.obj


    Fen::Fen(...) est définit dans le header que LGS.h inclus (fen.cpp). Mais je croyais avoir géré les problèmes de double inclusions dans LGS.h (avec le #ifndef), donc par extension dans Fen.cpp.

    De plus, si Losangeles.h n'inclus pas LGS, la compilation passe et il n'y a pas de bugs.

    Alors, quelqu'un saurait ce qui cloche dans mon programme?


    -
    Edité par BelhouariSéhane 8 février 2019 à 21:29:43

    • Partager sur Facebook
    • Partager sur Twitter
    Le basheur
      8 février 2019 à 21:46:31

      Salut,

      Pourquoi tu inclues un cpp ? Il faut pas faire ça !

      C'est ton fen.h que tu dois inclures. D'ailleurs pourquoi inclure LGS.h et pas fen.h directement ?

      • Partager sur Facebook
      • Partager sur Twitter
        9 février 2019 à 8:57:53

        Donc il ne faut pas inclure le cpp. Mais quand j'utilise le constructeur de classes de Visual C++, il créé le .h qui n'inclus pas le .cpp et le .cpp qui inclus le .h. Dans le main.cpp je peux inclure simplement le .h,  mais dès que je veux utiliser l'objet dans un autre projet, si j'inclus le .h, les fonctions du .cpp ne sont pas incluses automatiquement, alors j'ai inclus le .cpp à la place. Faut-il faire autrement?

        -
        Edité par BelhouariSéhane 9 février 2019 à 8:58:37

        • Partager sur Facebook
        • Partager sur Twitter
        Le basheur
          9 février 2019 à 9:13:47

          Attention à ne pas confondre deux choses.

          • faire un #include d'un fichier source pour que son contenu soit inséré, à la compilation, dans un autre source
          • déclarer qu'un fichier quelquechose.cpp  fait partie des sources qu'il faut compiler et lier pour fabriquer un exécutable du projet.
          • et trois : "mettre le source dans le répertoire du projet".

          Ne pas se mélanger aussi entre

          • compilateur qui vérifie les sources et les traduits en instructions placées dans des fichiers objets
          • éditeur de liens (linker) qui fabrique un exécutable à partir de fichiers objets et de bibliothèques
          • débugger qui suit ce qui se passe pendant l'exécution

          Un message d'erreur avec LNK, c'est clairement au niveau de l'édition des liens. Un fichier ou une fonction qui manque.

          Et redefinition, c'est que la même fonction a été définie deux fois, en général à cause d'un include malencontreux.

          -
          Edité par michelbillaud 9 février 2019 à 9:20:35

          • Partager sur Facebook
          • Partager sur Twitter
            9 février 2019 à 19:59:18

            Donc si je comprend bien c'est le .h que j'inclus n'importe où et le .cpp que je veille à n'inclure qu'une fois via les propriétées du projet dans "editeur de liens".

            Si j'ai vus juste, j'aimerais juste savoir comment mettre un .cpp en "entrée" (je n'ai lié auparavant que des .lib)

            • Partager sur Facebook
            • Partager sur Twitter
            Le basheur
              9 février 2019 à 20:43:00

              Presque.

              La problématique, c'est pourquoi inclure le LGS.h qui inclut le contenu de Fen.cpp qui est déjà compilé par ailleurs.

              Il peut arriver qu'on doive faire l'inclusion de code source avec des instructions, mais c'est en général quand ce code source a été lui même produit par programme (genre lex/yacc/etc.), ce n'est pas le cas dans les projets de débutants.

              -
              Edité par michelbillaud 9 février 2019 à 20:46:00

              • Partager sur Facebook
              • Partager sur Twitter
                9 février 2019 à 21:15:45

                Mais fen.cpp n'est pas compilé, c'est un document comme un texte.

                Et j'utilise LGS.h pour inclure plus facilement dans mon projet l'objet Fen (il peut pointer sa position..., et fen.h inclus déjà d'autres .h, donc je ne trouvais pas sécurisant de travailler directement avec fen.h ou .cpp

                -
                Edité par BelhouariSéhane 9 février 2019 à 21:18:57

                • Partager sur Facebook
                • Partager sur Twitter
                Le basheur
                  9 février 2019 à 21:21:11

                  Son contenu (de LGS.h) est compilé dans chaque unité de compilation où il est inclus, directement ou indirectement.

                  A savoir losAngeles.cpp et source.cpp.

                  La "garde" LGS_EST_DEF empêche les inclusions multiples _à l'intérieur_ d'une même unité de compilation.

                   ---

                  Faut pas faire le malin avec les inclusions en C++. Surtout, ne jamais faire des "fourretout.h" qui incluent une série de fichiers "pour pas s'embêter" (tu constates ce que ça donne...)

                  Règle générale : dans un source, on inclut les définitions des classes qu'on utilise dans le source. Toutes, et rien d'autre. Point barre.

                  -
                  Edité par michelbillaud 9 février 2019 à 21:27:44

                  • Partager sur Facebook
                  • Partager sur Twitter
                    9 février 2019 à 21:33:38

                    Alors je vais abandonner le LGS.h. Mais alors, pour inclure directement Fen à partir de Fen.h et Fen.cpp, je fais comment?
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Le basheur
                      9 février 2019 à 21:43:01

                      Si tu parles d'une classe Fen, elle devrait

                      • être définie dans Fen.h,
                      • avoir ses fonctions membres, y compris les constructeurs, définies dans Fen.cpp (qui fera un #include "Fen.h")

                      Avoir une définition de constructeur Fen::Fen dans un fichier .h, directement ou par inclusion, c'est anormal.

                      -
                      Edité par michelbillaud 9 février 2019 à 21:49:13

                      • Partager sur Facebook
                      • Partager sur Twitter
                        10 février 2019 à 11:07:21

                        Pour ça c'est tout bon, visual studio s'en est occupé, le fen.h est essentiellement compris entre 2 accolades et ne contiens que des prototypes, tandis que fen.cpp inclus fen.h et définis ses fonctions. Mais ma question est: comment dois-je inclure fen.h et fen.cpp

                        -
                        Edité par BelhouariSéhane 10 février 2019 à 11:08:07

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Le basheur
                          11 février 2019 à 13:31:49

                          Inclure dans quoi ???

                          Le .cpp inclus le .h vie #include.

                          Le .h DÉFINIT la classe, pas d'implémentation.

                          Si vous voulez inclure une classe dans un projet au niveau code source (pas de lib).

                          Vous ajoutez le .cpp dans la liste des fichiers sources du projet (en le copiant dans le répertoire du projet, ça serait plus propre, ainsi que le .h correspondant)

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

                          LNK2005: Problème de redéfinition

                          × 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