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 :

Éviter une prise de tête avec les Includes


Sujet :

C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 7
    Points : 7
    Points
    7
    Par défaut Éviter une prise de tête avec les Includes
    Bonjour,

    Je travaille sur un gros projet en ce moment, où il y a toute une hiérarchie de fichiers .h et .cpp, je code sous l'interface Visual Studio 2008 Pro.

    Le code compile sans problème jusque là, mais je me heurte à un problème d'inclusions cyclique...

    En effet, j'ai organisé les includes comme j'ai pu pour que ça compile (Avec des déclarations implicites de classes, des includes dans les fichiers .cpp ...), mais là le projet devenant assez conséquent je ne parviens plus à utiliser mes classes les unes avec les autres... (En fait, je n'arrive pas à inclure les fichiers).

    Les classes se terminent toutes par des ; , et un #pragma once se trouve en en tête de tous les fichiers .h .

    J'ai déjà parcouru les messages traitant ce genre de problème, mais sans trouver la solution 'miracle' (Si celle ci existe bien sûr ), ni de solution concernant mon plus gros soucis.

    Le plus gros problème que j'ai maintenant c'est que j'ai besoin d'utiliser une classe qui hérite dans une qui inclus déjà la classe héritée.

    Avec du code c'est plus clair ^^ :
    ClasseA.h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #pragma once
    class ClasseA
    {
    ...
    };
    ClasseB.h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #pragma once
    #include "ClasseA.h"
     
    class ClasseB : public ClasseA
    {
    ...
    };
    ClasseC.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
    #pragma once
    #include "ClasseA.h"
    #include "ClasseB.h"
     
    class ClasseC
    {
    ...
    private:
    // Réellement la méthode n'est pas inline
    void methode()
    {
    ClasseA* instance = new ClasseB();
    }
    };
    Comme la classe B hérite de A je ne peut pas faire de déclaration implicite de classe, ici le problème apparaîtra par une erreur sur la classe B : ClasseA inconnue.

    Bref, auriez vous une solution pour mon problème ou des astuces pour s'y retrouver dans les inclusions ? (Par exemple n'y a t-il pas moyen de tout inclure dans un seul fichier et d'utiliser celui ci dans tous les headers ?)

    Merci d'avance .

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Bonjour et bienvenu,
    1/ Effectivement les problématiques des fichiers d'en-tête sont régulièrement abordées et récemment ici.
    2/ L'exemple que tu proposes en étant trop simplifié ne reproduit pas le problème. Je compile parfaitement ce code.
    3/
    (Par exemple n'y a t-il pas moyen de tout inclure dans un seul fichier et d'utiliser celui ci dans tous les headers ?)
    C'est la garantie d'une dégradation du temps de compilation (la moindre modif entraînera une recompilation de tout ton projet), de la création d'un beau plat de spaghetti, de l'ossification de ton projet car tout devient indistinctement dépendant de tout... Bref, c'est une vraie fausse bonne idée.

    Peux-tu présenter un code qui reproduit ton problème ?

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 7
    Points : 7
    Points
    7
    Par défaut
    Effectivement, j'ai omis un détail important dans le bout de code, la classe ClasseC doit être connue presque partout, car elle possède des valeurs constantes importantes.

    Revoila le code :

    ClasseA :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #pragma once
     
    class ClasseA
    {
    public:
        ClasseA(void);
        ~ClasseA(void);
    };
    ClasseB :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #pragma once
    #include "classea.h"
    #include "classec.h"
     
    class ClasseB :
        public ClasseA
    {
    public:
        ClasseB(void);
        ~ClasseB(void);
    };
    ClasseC :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #pragma once
    #include "ClasseA.h"
    #include "ClasseB.h"
     
    class ClasseC
    {
    public:
        ClasseC(void);
        ~ClasseC(void);
        void test()
        {
            ClasseA* instance = new ClasseB();
        }
    };
    J'ai bien vérifié, le code retourne ces erreurs :
    Erreur 4 error C2061: erreur de syntaxe*: identificateur 'ClasseB'
    Erreur 1 error C2065: 'ClasseA'*: identificateur non déclaré
    Erreur 2 error C2065: 'instance'*: identificateur non déclaré
    Erreur 3 error C2061: erreur de syntaxe*: identificateur 'ClasseB'

    Merci .

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Lisp_ Voir le message
    Effectivement, j'ai omis un détail important dans le bout de code, la classe ClasseC doit être connue presque partout, car elle possède des valeurs constantes importantes.
    Problème de définition du périmètre de la classe : sort les constantes dans struct CDef qui est inclue partout et un class ClasseC avec ses éventuelles dépendances avec ClasseA&classeB. Au passage, tu peux utiliser le namespace pour 'scopper' tes constantes sans avoir à les encapsuler dans une classe/structure.

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ça me fait penser ça cette FAQ, tout ça...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 7
    Points : 7
    Points
    7
    Par défaut
    Merci pour ta contribution Médinoc, mais ce sont justement les déclarations anticipées qui m'ont permis d'aller jusque là (Je me suis mal exprimé en les qualifiant de déclarations implicites de classes), seulement elles ne fonctionnent apparemment plus lorsqu'il y a un héritage. (Les erreurs retournées sont du genre "Constructeur manquant")

    Je vais me pencher sur la solution proposée par 3DArchi, merci pour votre aide !

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Le problème, c'est que je ne vois pas de déclarations anticipées dans le code du post #3, donc les classe ClasseB et ClasseC sont croisées.

    Je pense que tu cherches à trop en faire dans les en-têtes.
    Déplace le corps de ton constructeur dans un fichier source à part, et ça devrait aller.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 7
    Points : 7
    Points
    7
    Par défaut
    J'ai appliqué la solution de 3DArchi, j'ai mis toutes les constantes dans une classe, et je l'ai inclus au besoin dans les autres, grâce à ça je n'ai plus de problème, il n'y a plus de déclarations anticipées et mon code est mieux structuré, bref, que du bonheur .

    Merci !

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

Discussions similaires

  1. Prise de tête avec une douchette
    Par serendib dans le forum WinDev
    Réponses: 6
    Dernier message: 05/09/2014, 12h09
  2. Réponses: 4
    Dernier message: 14/12/2012, 15h18
  3. Prise de tête avec les ""
    Par jeff1494 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 09/11/2009, 22h03
  4. Réponses: 4
    Dernier message: 23/10/2006, 09h09
  5. Comment faire une division par 5 avec les decalages
    Par Zaion dans le forum Assembleur
    Réponses: 7
    Dernier message: 05/11/2004, 17h33

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