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 :

Pb de croisement de classe


Sujet :

C++

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut Pb de croisement de classe
    Bonjour,

    j'ai adopté la technique décrite dans la faq au niveau de références croisées des classes :
    http://c.developpez.com/faq/cpp/?pag...erence_croisee

    MAIS j'ai un problème :
    Si on prend l'exemple de la faq, je n'arrive pas :
    1/ à déclarer dans A un objet B b (et non pas un pointeur B* b)
    2/ à déclarer dans A une fonction amie, membre de B, telle que :
    friend void B::fct();

    J'ai respectivement les erreurs suivantes:
    e:\dev\cdir.h(152) : error C2079: 'b' uses undefined class 'B'
    ET
    e:\dev\cdir.h(180) : error C2027: use of undefined type 'B'
    Si qqun à une idée ?

    @+

  2. #2
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Points : 444
    Points
    444
    Par défaut
    Le problème quand tu déclares un attribut objet est que cette déclration cache en fait un appel implicite au constructeur par défaut. Pour cela le compilateur a besoin de connaître le type, i.e que ce dernier ait été défini à ce moment de la compilation, et pas seulement déclaré comme c'est le cas avec la technique des références croisées.

    Idem pour la déclaration de la fonction amie, il faut que le type soit déjà défini et pas seulement déclaré.

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    Merci.

    Donc tel que je voulais le faire c'est pas possible ?
    alors c'est que j'ai dû choisir une mauvaise architecture ...

    Je vais arranger ça

    @+

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par olive_le_malin
    j'ai adopté la technique décrite dans la faq au niveau de références croisées des classes :
    http://c.developpez.com/faq/cpp/?pag...erence_croisee

    MAIS j'ai un problème :
    Si on prend l'exemple de la faq, je n'arrive pas :
    1/ à déclarer dans A un objet B b (et non pas un pointeur B* b)
    C'est normal. Pose-toi la question de ca que vaudrais sizeof (A) ?

    Citation Envoyé par olive_le_malin
    2/ à déclarer dans A une fonction amie, membre de B, telle que :
    friend void B::fct();
    Effectivement, je ne vois pas de moyen de résoudre ça a priori. A moins bien entendu d'étendre l'amitié à toute la classe. En effet, le standard dit (11.4.7) :
    A name nominated by a friend declaration shall be accessible in the scope of the class containing the friend declaration.

    Dans ton cas, je ne vois pas de moyen de faire connaître au compilateur le nom B::fct.
    Ce problème ne m'est encore jamais arrivé sur du vrai code. Ton problème venait d'un cas concrêt, ou d'une exploration du langage ?
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Points : 444
    Points
    444
    Par défaut
    Et si tu inclues le header contenant B dans le header définissant A, ça ne marche pas ? Il suffit de n'avoir aucune référence à un objet de type A ou à un de ses membres dans le header définissant B et ça devrait passer non ?

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    Bonjour,

    Citation Envoyé par JolyLoic
    C'est normal. Pose-toi la question de ca que vaudrais sizeof (A) ?
    que veux-tu dire, un truc qui se mort la queue ?
    car un objet B contient un objet A, qui lui-même contient un objet B, ...
    Ha ouais ça va faire beaucoup ça non ?


    Citation Envoyé par JolyLoic
    Dans ton cas, je ne vois pas de moyen de faire connaître au compilateur le nom B::fct.
    Ce problème ne m'est encore jamais arrivé sur du vrai code. Ton problème venait d'un cas concrêt, ou d'une exploration du langage ?
    Heu ... un peu des deux. Disons un cas contret que j'essaie de "compliquer" pour explorer le langage.
    Bon, mais comme je le disais j'avais eut être fait un mauvais choix d'archi. Je l'ai repensé, et là ça marche.

    Citation Envoyé par bolhrak
    Et si tu inclues le header contenant B dans le header définissant A, ça ne marche pas ? Il suffit de n'avoir aucune référence à un objet de type A ou à un de ses membres dans le header définissant B et ça devrait passer non ?
    Non ... voir la remarque de JolyLoic

    @+

  7. #7
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Points : 444
    Points
    444
    Par défaut
    Citation Envoyé par olive_le_malin
    Bonjour,

    Non ... voir la remarque de JolyLoic

    @+
    Euh je crois qu'on s'est pas compris :

    Citation Envoyé par JolyLoic
    A name nominated by a friend declaration shall be accessible in the scope of the class containing the friend declaration.
    Donc je vois pas trop où ça contredit ce que j'ai dit, au contraire.

    fichier B.h :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    class A;
     
    class B {
     
        private:
     
            A* p_a;
    };
    et fichier A.h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include B.h
     
    class A {
     
        private:
     
            B b;
            friend void B::fct();
    };
    Ca marche très bien chez moi.

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    Bonjour,

    et bien oui c''est normal que ça marche : tu as inversé A et B par rapport à la faq.
    Donc le problème consisterait pour toi à :
    1/ à déclarer dans B un objet A a
    --> Mais ça j'ai compris que c'était débile (enfin je pense)
    2/ à déclarer dans B une fonction amie, membre de A, telle que :
    friend void A::fct();

    @+

  9. #9
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Points : 444
    Points
    444
    Par défaut
    Citation Envoyé par olive_le_malin
    Bonjour,

    et bien oui c''est normal que ça marche : tu as inversé A et B par rapport à la faq.
    Euh peut être mais c'est exactement ce que tu cherches à faire dans ton premier post il me semble ... SI j'ai mal compris désolé pour le quiproquo.

    Citation Envoyé par olive_le_malin
    Donc le problème consisterait pour toi à :
    1/ à déclarer dans B un objet A a
    --> Mais ça j'ai compris que c'était débile (enfin je pense)
    Pas forcément, si ton objet contenu est forcément initialisé par son conteneur, et que tu n'as pas de polymorphisme à exploiter, je ne vois pas en quoi ce serait débile. Lorsque tu utilises une liste par exemple, tu ne déclares pas un pointeur sur liste, tu déclares directement l'objet.

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    Citation Envoyé par bolhrak
    Euh peut être mais c'est exactement ce que tu cherches à faire dans ton premier post il me semble ... SI j'ai mal compris désolé pour le quiproquo.
    Aucun problème ...
    Moi ce que je demandais c'était de pouvoir déclarer un A a dans B, et B b dans A ... c'est à dire que si on prends l'exemple de la faq remplacer le
    B* PtrB; par B objB;
    Et déclarer avec la même logique croisée, une fonction membre de B amie de A, et une fonction membre de A amie de B


    Citation Envoyé par bolhrak
    Pas forcément, si ton objet contenu est forcément initialisé par son conteneur, et que tu n'as pas de polymorphisme à exploiter, je ne vois pas en quoi ce serait débile. Lorsque tu utilises une liste par exemple, tu ne déclares pas un pointeur sur liste, tu déclares directement l'objet.
    Oui mais là c'est différent. C'est déclarer un objet A qui a pour membre un objet B qui a lui même pour membre un objet A, qui a lui même ...
    En tout cas, ça pour moi, ça me semble pas trés logique.

    Ou alors c'est moi qui suis pas logique, mais bon ...

  11. #11
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Points : 444
    Points
    444
    Par défaut
    Citation Envoyé par olive_le_malin
    Aucun problème ...
    Moi ce que je demandais c'était de pouvoir déclarer un A a dans B, et B b dans A ... c'est à dire que si on prends l'exemple de la faq remplacer le
    B* PtrB; par B objB;
    Et déclarer avec la même logique croisée, une fonction membre de B amie de A, et une fonction membre de A amie de B
    Effectivement je suis reparti dans l'esprit de mon premier message, c'est-à-dire que tu ne pouvais pas faire de référence croisée en déclarant deux attributs de type objet, et non pointeur. Partant de là je pensais donc que le fait qu'un soit déclaré pointeur était implicite, et je répondais dans cette optique.

    Citation Envoyé par olive_le_malin
    Oui mais là c'est différent. C'est déclarer un objet A qui a pour membre un objet B qui a lui même pour membre un objet A, qui a lui même ...
    En tout cas, ça pour moi, ça me semble pas trés logique.

    Ou alors c'est moi qui suis pas logique, mais bon ...
    Même remarque que dans le cas précédent je suis partir du fait qu'un des attributs était un pointeur. Bref c'est vrai que j'ai pas forcément été très clair

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

Discussions similaires

  1. Classe pour la création d'un graphe xy
    Par Bob dans le forum MFC
    Réponses: 24
    Dernier message: 03/12/2009, 17h20
  2. Réponses: 31
    Dernier message: 30/03/2006, 16h57
  3. Élaboration de classe
    Par il_a_ri dans le forum Langages de programmation
    Réponses: 6
    Dernier message: 16/01/2003, 14h22
  4. Variable d'une Classe Ancêtre
    Par Génie dans le forum Langage
    Réponses: 3
    Dernier message: 18/09/2002, 19h24
  5. Sortir un typedef d'une classe
    Par Theophil dans le forum C++Builder
    Réponses: 13
    Dernier message: 03/07/2002, 17h21

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