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 :

Définition de 2 classes possédant chacune des Ptr vers des objets de l'autre


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2008
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 18
    Par défaut Définition de 2 classes possédant chacune des Ptr vers des objets de l'autre
    Bonjour,

    Le titre n'est pas très représentatif mais je ne sais pas comment le dire...

    Contexte :

    Je développe une application utilisant un maillage (algo de DELAUNAY) et je cré plusieurs objet dont "Triangle" et "Segment". Pour mettre en place cet algo j'ai besoin que ma classe Triangle possède 3 pointeurs vers des objets type Segment (logique un triangle à bien 3 arêtes) donc la pas de Pb mais j'ai également besoin que ma classe Segment possède 2 pointeurs vers des objets type Triangle (les 2 triangles juxtaposés du maillage partageant le segment en question.)

    J'ai donc voulu déclarer mes classes comme cela :

    Pour la classe Triangle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #ifndef TRIANGLE
    #define TRIANGLE
     
    #include <Segment.h>
     
    class Triangle
    {
     
        public :
     
            Segment *S1, *S3, *S3;
    };
    #endif
    Pour la classe Segment :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #ifndef SEGMENT
    #define SEGMENT
     
    #include <Triangle.h>
     
    class Segment
    {
     
        public :
     
            Triangle *Tv1, *Tv2;
    };
    #endif
    Le Hic c'est que ca plante à la compilation sur la ligne 11 de la classe Triangle : 'Segment' does not name a type'.

    => Si je comprend bien c'est qu'il ne connait pas le type 'Segment' à ce moment là alors qu'il est bien défini en include.

    Si je supprime #include <Triangle.h> de la classe Segment, le problème disparait mais je ne peux alors plus avoir de pointeurs vers des triangles dans cette classe ce qui est problématique.

    Je sens bien que ca ne peut pas marcher comme cela puisque chaque classe a besoin de l'autre pour être définie mais comment solutionner proprement ce problème ?

    Merci d'avance pour votre aide, et désolé si la réponse est obvious, je débute en programmation.

    Bien cordialement,

    Nico

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 152
    Billets dans le blog
    4
    Par défaut
    Il faut utiliser une forward declaration dans les header.
    En fait il faut toujours préférer les forward declaration dans les header et favoriser les include dans les fichiers sources.
    http://cpp.developpez.com/faq/cpp/?p...-une-a-l-autre
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2008
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 18
    Par défaut
    Merci Bousk pour ta réponse.

    J'ai consulté le lien dans la FAQ qui explique ce qu'est la déclaration anticipée. J'ai modifié ma classe Segment ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #ifndef SEGMENT
    #define SEGMENT
     
    #include <Triangle.h> :  // Ligne supprimée
    
    Class Triangle;
     
    class Segment
    {
     
        public :
     
            Triangle *Tv1, *Tv2;
    };
    Cela compile sans problème.

    Par contre peux tu me détailler ce que tu veux dire par :
    En fait il faut toujours préférer les forward declaration dans les header et favoriser les include dans les fichiers sources.
    Car au final je déclare toujours mes classes dans un header (un par classe) et y ajoute en tête tous les includes nécessaires au fonctionnement de la classe. Exemple concret :
    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
    #ifndef TRIANGLE
    #define TRIANGLE
     
    #include <QPoint>
    #include <QVector>
     
    #include <cmath>
    #include <C_Mesh/Segment.h>
     
    #include <C_Generique/Maths.h>
     
    class Triangle
    {
     
        //
    }
    #endif
    Comment devrais je appliquer ce principe ici par exemple ? le pourrais je ?

    Merci encore pour ton intervention

  4. #4
    Membre émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    736
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 736
    Par défaut
    Bonjour.

    La forward declaration ne fonctionne qu'avec des pointeurs, si tu déclares :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Foo{
        Objet obj;
    };
    , tu seras obligé d'inclure la déclaration d'Objet (#include<objet.h> //ou autre.

    Si tu utilises exclusivement des pointeurs d'Objet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Foo{
        Objet *obj;
    };
    , tu peux sans problème écrire class Objet; avant de déclarer class Foo {}.
    En revanche l'include sera déplacé dans la définition de Foo, dans le fichier cpp.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Février 2008
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 18
    Par défaut
    Merci Daïmanu pour ta réponse, je crois que je comprend bien la déclaration anticipée.

    Est ce obligatoire de placer le #include <Objet.h> dans le fichier Foo.cpp ou pourrait on créer un fichier GenericInclude.h qui contiendrait tous les includes nécessaires à toutes les classes du projet ? L'avantage serait de ne les spécifier qu'une seule fois ...

  6. #6
    Membre émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    736
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 736
    Par défaut
    Tu peux créer un gros fichier d'include.

    L'inconvénient est que ça va allonger la compilation, vu que chaque fichier cpp va recevoir tout le contenu de tous les fichiers inclus.
    De plus, il risque d'y avoir des problèmes de collision si les fichiers définissent des macros / classes / variables avec le même nom.

    Généralement on recommande de n'inclure uniquement ce dont on a besoin.

  7. #7
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2011
    Messages
    223
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 223
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Il faut utiliser une forward declaration dans les header.
    En fait il faut toujours préférer les forward declaration dans les header et favoriser les include dans les fichiers sources.
    http://cpp.developpez.com/faq/cpp/?p...-une-a-l-autre
    Je suis d'accord mais il faut préciser que ce n'est possible qu'à condition d'utiliser des pointeurs ou des références vers les objets ces ces classes, pas directement des instances. Ce qui est d'ailleurs aussi une bonne pratique.

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 152
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par olreak Voir le message
    Je suis d'accord mais il faut préciser que ce n'est possible qu'à condition d'utiliser des pointeurs ou des références vers les objets ces ces classes, pas directement des instances. Ce qui est d'ailleurs aussi une bonne pratique.
    Conceptuellement si tu arrives à avoir une classe A composée d'une classe B elle-même composée d'une classe A
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    class A { B b; };
    class B { A a; };
    C'est même plus du wtf là, c'est carrément de la folie. Tu te retrouves avec A qui contient un B qui contient un A, qui.....
    Je préfère pas penser que quelqu'un puisse l'imaginer.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Février 2008
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 18
    Par défaut
    Merci à tous pour vos réponses, je pense avoir bien saisi la bonne facon de faire. Ne reste plus qu'à l'appliquer en reprenant le code déjà écrit !

    Encore merci

Discussions similaires

  1. Réponses: 3
    Dernier message: 05/09/2011, 12h53
  2. Réponses: 5
    Dernier message: 04/05/2009, 14h54
  3. Réponses: 3
    Dernier message: 13/09/2007, 18h11
  4. [ETAT]Créer des liens vers des entetes de groupes
    Par tonyice80 dans le forum IHM
    Réponses: 7
    Dernier message: 06/04/2007, 23h37
  5. Réponses: 3
    Dernier message: 23/01/2007, 08h14

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