IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

compilation multi fichiers


Sujet :

C++

  1. #1
    Membre averti

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 313
    Points : 404
    Points
    404
    Billets dans le blog
    14
    Par défaut compilation multi fichiers
    Salut aux développeurs en C++,


    j'ai un problème de multi-fichier.
    j'ai un fichier qui utilise des classes et des types enumérations d'un autre fichier:

    competence.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
     
    class competence{
       private:
          un_de le_de;
          personnage *P_personnage;
       public:
          competence();
          int lancer_de();
          int accesseur_For();
          int accesseur_Dex();
          int accesseur_Con();
          int accesseur_Int();
          int accesseur_Sag();
          int accesseur_Cha();
          race accesseur_ra();
          classe accesseur_cl();
          virtual int accesseur_caract();
    };
     
    competence::competence():le_de(20){}
     
    int competence::lancer_de(){
       return le_de.lance();
    }
     
    int competence::accesseur_For(){
       return P_personnage->accesseur_For();
    }
     
    int competence::accesseur_Dex(){
       return  P_personnage->accesseur_Dex();
    }
     
    int competence::accesseur_Con(){
       return  P_personnage->accesseur_Con();
    }
     
    int competence::accesseur_Int(){
       return  P_personnage->accesseur_Int();
    }
     
    int competence::accesseur_Sag(){
       return  P_personnage->accesseur_Sag();
    }
     
    int competence::accesseur_Cha(){
       return  P_personnage->accesseur_Cha();
    }
     
    race competence::accesseur_ra(){
       return  P_personnage->accesseur_ra();
    }
     
    classe competence::accesseur_cl(){
       return  P_personnage->accesseur_cl();
    }
    g++ -c competence.cpp me donne ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    competence.cpp:3: erreur: 'un_de' does not name a type
    competence.cpp:4: erreur: ISO C++ forbids declaration of 'personnage' with no type
    competence.cpp:4: erreur: expected ';' before '*' token
    competence.cpp:14: erreur: 'race' does not name a type
    competence.cpp:15: erreur: 'classe' does not name a type
    competence.cpp: In constructor 'competence::competence()':
    competence.cpp:19: erreur: class 'competence' does not have any field named 'le_de'
    competence.cpp: In member function 'int competence::lancer_de()':
    competence.cpp:22: erreur: 'le_de' was not declared in this scope
    competence.cpp: In member function 'int competence::accesseur_For()':
    competence.cpp:26: erreur: 'P_personnage' was not declared in this scope
    competence.cpp: In member function 'int competence::accesseur_Dex()':
    competence.cpp:30: erreur: 'P_personnage' was not declared in this scope
    competence.cpp: In member function 'int competence::accesseur_Con()':
    competence.cpp:34: erreur: 'P_personnage' was not declared in this scope
    competence.cpp: In member function 'int competence::accesseur_Int()':
    competence.cpp:38: erreur: 'P_personnage' was not declared in this scope
    competence.cpp: In member function 'int competence::accesseur_Sag()':
    competence.cpp:42: erreur: 'P_personnage' was not declared in this scope
    competence.cpp: In member function 'int competence::accesseur_Cha()':
    competence.cpp:46: erreur: 'P_personnage' was not declared in this scope
    competence.cpp: At global scope:
    competence.cpp:49: erreur: 'race' does not name a type
    competence.cpp:53: erreur: 'classe' does not name a type
    tandis que si j'ajoute "class un_de;" et "class personnage;" au début du fichier "competence.cpp":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    g++ -c competence.cpp me donne:
    competence.cpp:5: erreur: field 'le_de' has incomplete type
    competence.cpp:16: erreur: 'race' does not name a type
    competence.cpp:17: erreur: 'classe' does not name a type
    competence.cpp: In constructor 'competence::competence()':
    competence.cpp:21: erreur: class 'competence' does not have any field named 'le_de'
    competence.cpp: In member function 'int competence::lancer_de()':
    competence.cpp:24: erreur: 'le_de' was not declared in this scope
    competence.cpp: In member function 'int competence::accesseur_For()':
    competence.cpp:28: erreur: invalid use of incomplete type 'struct personnage'
    competence.cpp:2: erreur: forward declaration of 'struct personnage'
    competence.cpp: In member function 'int competence::accesseur_Dex()':
    competence.cpp:32: erreur: invalid use of incomplete type 'struct personnage'
    competence.cpp:2: erreur: forward declaration of 'struct personnage'
    competence.cpp: In member function 'int competence::accesseur_Con()':
    competence.cpp:36: erreur: invalid use of incomplete type 'struct personnage'
    competence.cpp:2: erreur: forward declaration of 'struct personnage'
    competence.cpp: In member function 'int competence::accesseur_Int()':
    competence.cpp:40: erreur: invalid use of incomplete type 'struct personnage'
    competence.cpp:2: erreur: forward declaration of 'struct personnage'
    competence.cpp: In member function 'int competence::accesseur_Sag()':
    competence.cpp:44: erreur: invalid use of incomplete type 'struct personnage'
    competence.cpp:2: erreur: forward declaration of 'struct personnage'
    competence.cpp: In member function 'int competence::accesseur_Cha()':
    competence.cpp:48: erreur: invalid use of incomplete type 'struct personnage'
    competence.cpp:2: erreur: forward declaration of 'struct personnage'
    competence.cpp: At global scope:
    competence.cpp:51: erreur: 'race' does not name a type
    competence.cpp:55: erreur: 'classe' does not name a type
    dois-je redéfinir mes classes et enumérations dans competence.cpp?
    ou quelqu'un a une idée?

    je vous remercie

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    La première erreur, et une grosse partie de celles qui suivent, dans la première tentative de compilation du fichier vient du fait que le type un_de est inconnu.

    Lors de la deuxième tentative (celle dans laquelle tu utilise la déclaration anticipée du type un_de) échoue parce que tu ne peux te contenter de la déclaration anticipée d'un type que si tu y fait référence sous la forme d'un pointeur ou... d'une référence, justement, et que tu n'essaye pas d'accéder à son contenu.

    Comme ta variable de_le qui est du type un_de n'est ni une référence ni un pointeur, la déclaration anticipée ne fonctionne pas, et c'est la définition complète du type en question qui est nécessaire.

    Tu dois donc inclure le fichier d'en-tête (*.h / *.hpp) dans lequel se trouve la déclaration de la classe avant de pouvoir envisager déclarer une variable de ce type.

    En ce qui concerne le pointeur vers un objet de type Personnage nommé P_personnage, tu peux envisager de te contenter de la déclaration anticipée lorsque tu le déclare dans la définition de ta classe parce que c'est un pointeur, mais, encore une fois, si tu essaye d'accéder au contenu de ce pointeur (AKA: d'appeler n'importe quelle fonction membre de la classe Personnage), il te faut, encore une fois, disposer de la définition complète de la classe, et donc, inclure le fichier d'en-tête dans lequel elle se trouve.

    C'est une des raisons pour laquelle il est conseillé d'utiliser deux types de fichiers en C++: un fichier d'en-tête (*.h ou *.hpp) qui contient les déclarations des fonctions libres et la définition des classes, structures, unions et énumération et un fichier d'implémentation (*.cpp) qui inclus le fichier d'en-tête et qui contiendra... l'implémentation des fonctions libres et fonctions membres de ta classe ou de ta structure.

    Au final, si tu as trois classes nommées respectivement un_de Personnage et competence, tu auras sans doute six fichiers, organisés plus ou moins comme suit:
    un_de.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    /* Les directives #ifndef #define #endif servent de gardes 
     * anti inclusion multiples
     */
    #ifndef UN_DE_H
    #define UN_DE_H
    class un_de
    {
        /* contenu de la classe, par exemple */
        public:
            un_de(); //constructeur
            ~un_de(); // destructeur
            void foo(); // une fonction membre
    };
    #endif // UN_DE_H
    un_de.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    /* nous avons besoin de la définition de la classe... 
     * nous l'obtenons en incluant le fichier d'en-tête
     */
    #include "un_de.h"
    //définition du constructeur
    un_de::un_de()
    {
    }
    // définition du destructeur
    un_de::~un_de()
    {
    }
    // définition de la fonction membre
    void un_de::foo()
    {
    }
    personnage.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #ifndef PERSONNAGE_H
    #define PERSONNAGE_H
    class personnage
    {
        /* contenu de la classe, comme */
        public:
            personnage(); // constructeur
            ~personnage(); // destructeur
            void bar(); // une fonction membre
    };
    #endif
    personnage.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include "personnage.h"
    personnage::personnage()
    {
    }
    personnage::~personnage()
    {
    }
    void personnage::bar()
    {
    }
    Pour définir la classe compétence, il nous faut, dans competence.h:
    la définition de la classe un_de
    la déclaration uniquement de la classe Personnage
    cela nous donnera un fichier proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    #include "un_de.h"
    #ifndef COMPETENCE_H
    #define COMPETENCE_H
    // déclaration anticipée de Personnage, car cela nous suffit ici
    class personnage;
    class competence
    {
        public:
            Competence();
            ~Competence();
        private:
            un_de le_de;
            personnage * P_personnage;
    };
    #endif //COMPETENCE_H
    Pour l'implémentation, il en va autrement: il nous faut la définition complete aussi bien de un_de que de Personnage...

    Comme on dispose déjà de l'inclusion de un_de.h dans le fichier competence.h, le fichier competence.cpp peut prendre la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // provoque l'inclusion "en cascade" de un_de.h
    #include "competence.h" 
    // ici, il faut connaitre le contenu de la classe Personnage
    #include "personnage.h" 
    competence::competence()
    {
    }
    competece::~competence()
    {
    }
    /*...*/
    Ceci dit, il serait intéressant pour toi de déterminer et d'homogénéiser, au moins pour ton projet, une convention de nommage claire pour ce qui est des noms de classes, de structures et de variables et de t'y tenir.

    En effet, avant même de faire ce que l'on attend de lui, la première qualité d'un code source est d'être facilement lisible et compréhensible par la personne qui l'a sous les yeux...

    Le fait de pouvoir déterminer facilement les règles qui régissent la création des noms de types et de variables est, réellement, de nature à faciliter non seulement la lecture et la compréhension, mais aussi l'utilisation, en évitant de se poser la question quant à savoir si, par exemple, le nom de tel membre ou de telle fonction commence par une majuscule ou une minuscule
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre averti

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 313
    Points : 404
    Points
    404
    Billets dans le blog
    14
    Par défaut
    merci koala01, ça marche nikel...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 07/05/2009, 20h29
  2. [MASM] Compiler un fichier .sys ?
    Par - Robby - dans le forum x86 16-bits
    Réponses: 12
    Dernier message: 08/01/2008, 11h28
  3. [SOAP]Compilation du fichier stdsoap2.cpp (gSoap)
    Par Neo41 dans le forum C++Builder
    Réponses: 2
    Dernier message: 11/02/2005, 14h55
  4. Réponses: 1
    Dernier message: 18/06/2004, 01h12
  5. Réponses: 2
    Dernier message: 25/10/2002, 22h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo