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 :

probleme inclusion cyclique avec namespace


Sujet :

C++

  1. #1
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Points : 833
    Points
    833
    Par défaut probleme inclusion cyclique avec namespace
    Bonjour,
    tout est dans le titre, j'ai simplifier mon problème en deux fichiers et deux classes:
    fichier A.hxx
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #ifndef DEF_A_HXX
    #define DEF_A_HXX
     
    class B;
    namespace NS_A{
    class A 
    {
      void func(const B& one_b);
    };
    };
    #endif
    fichier B.hxx
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #ifndef DEF_B_HXX
    #define DEF_B_HXX
    #include "A.hxx"
    namespace NS_B{
    class B 
    {
      int a;
      NS_A::A* one_a;
    };
    };
    #endif
    B inclut A qui a besoin de B seulement la pré déclaration de B dans A ne résout pas le problème vu que B != NS_B (même si ça compile si je lance la méthode func avec un objet NS_B ça ne passe pas ).
    Pour que cela fonctionne il faudrait pré déclarer
    dans A.hxx mais ce n'est pas possible vu que NS_B n'est pas connu à ce stade.
    Quelqu'un à les idées plus claires que moi sur ce coup ? merci
    Linux > *

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

    Informations professionnelles :
    Activité : aucun

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

    Place ta déclaration anticipée dans l'espace de noms, si c'est dans l'espace de noms que tu fera l'implémentation de la classe ...

    On n'a jamais dit que la déclaration anticipée d'une classe devait forcément se faire au tout début d'un fichier

    Cela donnerait quelque chose 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
    #ifndef A_HPP
    #define A_HPP
    namespace NS_B // uniquement pour que la déclaration anticipée soit dans
                   // le bon espace de noms ( B != NS_A::B )
    {
        class B;
    } // namespace NS_B
    namespace NS_A
    {
        class A
        {
            /*...*/
        };
    } // namespace NS_A
    endif // A_HPP
    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
    #ifndef B_HPP
    #define B_HPP
    namespace NS_A // uniquement pour que la déclaration anticipée soit dans
                   // le bon espace de noms ( A != NS_B::A )
    {
        class A;
    } // namespace NS_A
    namespace NS_B
    {
        class B
        {
            /*...*/
        };
    } // namespace NS_B
    endif // B_HPP
    Mais, peut-être as tu choisi une granularité trop fine pour tes espaces de noms: ne serait il pas intéressant de regrouper les deux classes dans un espace de noms unique

    En effet, le but d'un espace de noms est de regrouper dans une "boite" ce qui "va ensemble" en le séparant clairement "du reste".

    Il est donc toujours possible d'avoir des "transferts" entre les espaces de noms (une classe de l'espace de noms game qui accède à une classe de l'espace de noms sound, et réciproquement, par exemple), mais l'idée reste quand même de faire en sorte que ces transferts soient aussi limités que possibles
    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 éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Points : 833
    Points
    833
    Par défaut
    Merci pour ton éclairage,
    Je me suis acharné à essayer de faire compiler le "class NS_B::B" sans penser à la méthode de déclaration de namespace

    Je vais repenser à la nécessité du namespace de B;
    Dans mon vrai code il s'agit d'un namespace de type utilitaire mais dont certains mots peuvent rentrer en conflit avec ceux de l'autre namespace et en plus à l'origine l'inclusion ne se faisait que dans un sens.
    Mais maintenant que j'ai le besoin de B dans A la question de sont utilité se pose en effet.
    Linux > *

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 616
    Points : 30 635
    Points
    30 635
    Par défaut
    Si tu n'as besoin que des classe qui se trouvent dans NS_B dans l'espace de noms NS_A, et que tu n'a pas besoin des classes se trouvant dans NS_A depuis NS_B, il peut rester cohérent d'avoir les deux espaces de noms.

    Mieux, si certaines classes de NS_A ont besoin de certaines classes de NS_B et que d'autres classes de NS_B ont besoin d'autres classes de NS_A, il peut rester cohérent de garder cette séparation "physique".

    Cependant, tu perds la possibilité d'utiliser au minimum un des deux espaces de noms sans avoir à t'inquiéter de... l'existence de l'autre, ce qui est finalement assez dommage .

    L'idéal reste en effet d'envisager le contenu des espaces de noms comme un module, qui doit pouvoir (ou peut s'en faut) être utilisé de manière autonome.

    Si je prend l'exemple d'un jeu video, on peut estimer que tout ce qui est nécessaire au jeu se trouve dans l'espace de noms MyGame.

    Parmi les différents éléments que nous utiliserons, nous trouverions sans doute des objets utilisés pour le son, l'affichage, l'intelligence artificielle, ... .

    Et nous aurions donc sans doute des espaces de noms tels que Sound, Screen, IA, ..., la plupart n'interagissant pas avec les autres.

    Tu pourrais donc décider de récupérer l'ensemble de ce qui se trouve dans l'espace de noms Sound, par exemple, pour un autre jeu, pour lequel tu aurait une conception au niveau de l'affichage ou de l'intelligence artificielle totalement différente.

    Mais, comme rien n'est jamais si simple, on se rend compte qu'il y a sans doute aussi une grande quantité de classes, peut être générique, mais pas forcément, qui sont utilisées dans les différents espaces de noms.

    Ce sont des classes que l'on pourrait définir comme faisant partie... du noyau de l'application.

    Elles seraient donc, idéalement, définies dans l'espace de noms... Kernel, et nous remarquerions alors que Sound, Screen et AI dépendent... de Kernel.

    Cela ne pose a priori pas de problème majeur, tant que Kernel ne dépend ni de Sound, ni de Screen, ni de AI, mais cela impose une restriction supplémentaire pour le jeu suivant qui voudrait utiliser l'espace de noms Sound: le fait que, quoi que l'on fasse pour l'affichage ou pour l'intelligence artificielle, nous serons "limités" par l'existant dans... Kernel, qu'il nous sera assez difficile de modifier sans devoir modifier... Sound.

    Or c'est, justement, ce que l'on espère pouvoir éviter en récupérant Sound

    Et, bien sur, ce qui devient un "léger problème" lorsque tu as des dépendances "à sens unique" entre les espaces de noms peut facilement se transformer en véritable casse-tête si tu as des dépendances plus ou moins circulaires entre les différents espaces de noms

    Ce sur quoi j'essaye ici d'attirer ton attention, c'est sur le fait que, bien sur, l'utilisation d'espace de noms est utile, nécessaire, indispensable pour te permettre d'organiser correctement ton projet, mais que l'excès nuit en tout, et que, si tu te retrouves avec des espaces de noms qui ne contiennent qu'un nombre très restreint de classes et quelques constantes globales, ou que tu finis par te retrouver avec des dépendances circulaires entre les espaces de noms, il faut réfléchir en vue de simplifier un peu les choses

    Évidemment, il y aura des cas dans lesquels il sera indispensable de suivre ce conseil, et, comme rien n'est jamais tout blanc ou tout noir dans la vie, il y aura également des cas dans lesquels ce conseil sera... à jeter aux orties
    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

  5. #5
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Points : 833
    Points
    833
    Par défaut
    Tu as bien cerner mon problème,
    Dans mon code NS_A correspond à un namespace de type "Kernel" et NS_B de type utilitaire "Geometry".
    Je pense pouvoir m'en sortir merci des infos
    Linux > *

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

Discussions similaires

  1. [XSLT] Probleme de selection avec namespaces
    Par Ludo_xml dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 01/06/2005, 14h32
  2. Réponses: 6
    Dernier message: 04/04/2003, 15h28
  3. [Kylix] Probleme de séparateur avec Kylix2 ?
    Par jeanphy dans le forum EDI
    Réponses: 4
    Dernier message: 10/02/2003, 16h41
  4. Réponses: 12
    Dernier message: 23/10/2002, 11h56
  5. Probleme d'impression avec la méthode TForm->Print()
    Par Kid Icarus dans le forum C++Builder
    Réponses: 13
    Dernier message: 31/07/2002, 14h26

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