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

Langage C++ Discussion :

Problème d'inclusion de fichiers d'en-tête


Sujet :

Langage C++

  1. #1
    Membre régulier Avatar de Nadd
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 160
    Points : 95
    Points
    95
    Par défaut Problème d'inclusion de fichiers d'en-tête
    Bonjour,

    J'éprouve quelques difficultés à résoudre un problème d'inclusion de fichiers d'en-tête. La situation est simple : j'ai deux classes, définies et implémentées dans leur fichier .hpp, qui s'utilisent mutuellement. Vous trouverez ci-dessous la structure générale de ces deux classes.

    Fichier point.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
    16
    17
    18
    19
    20
    21
    #ifndef POINT_H_INCLUDED
    #define POINT_H_INCLUDED
     
    class circular_dll;
     
    class point
    {
    public:
    	point() { _x = 0; _y = 0; _value = 0; _index = 0; _adjacencies = new circular_dll(); }
     
            ~point() { ... }
     
    ...
     
    private:
    	int _index;
    	double _x, _y, _value;
    	circular_dll *_adjacencies;
    };
     
    #endif
    Fichier circular_dll.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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #ifndef CIRCULAR_DLL_H_INCLUDED
    #define CIRCULAR_DLL_H_INCLUDED
     
    class point;
     
    #include "point.hpp"
     
    class circular_dll
    {
    public:
    	circular_dll() { first = nullptr; last = nullptr; }
     
    	~circular_dll()
    	{ ... }
     
    ...
     
    private:
    	class node
    	{
    	public:
    		point *data;
    		node *prev, *next;
    	private:
    	};
     
    	node *first, *last, *cursor;
    };
     
    #endif
    À la compilation, l'erreur provient de la ligne de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _adjacencies = new circular_dll();
    'circular_dll' : no appropriate default constructor available
    Lorsque j'ajoute #include "circular_dll.hpp" dans le fichier point.hpp, la classe point devient inutilisable dans le fichier circular_dll.hpp, à cause de l'inclusion circulaire des en-têtes, malgré les #ifndef.

    En vous remerciant d'avance,

    Nicolas.

  2. #2
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut
    Essaye une fois quelque chose du genre (en séparant définition et implémentation):

    class Point.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
    16
    #ifndef POINT_H_INCLUDED
    #define POINT_H_INCLUDED
    class circular_dll;
     
    class point
    {
    public:
           point();
          ~point();
     
    private:
    	int _index;
    	double _x, _y, _value;
    	circular_dll *_adjacencies;
    };
    #endif
    class Point.cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Point::point() { _x = 0; _y = 0; _value = 0; _index = 0; _adjacencies = new circular_dll(); }
    ....
    Idem pour circular_dll.

  3. #3
    Membre régulier Avatar de Nadd
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 160
    Points : 95
    Points
    95
    Par défaut
    Merci pour votre réponse.

    Voici l'erreur que j'obtiens en séparant l'implémentation de la définition :
    'circular_dll' : no appropriate default constructor available
    Par ailleurs, j'ai remarqué que le problème venait d'autre part. Dans mon fichier main.cpp, j'inclus le fichier point.hpp. Si je retire l'inclusion, ça compile.

  4. #4
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Août 2011
    Messages : 342
    Points : 1 091
    Points
    1 091
    Par défaut
    Citation Envoyé par Nadd Voir le message
    Merci pour votre réponse.

    Voici l'erreur que j'obtiens en séparant l'implémentation de la définition :


    Par ailleurs, j'ai remarqué que le problème venait d'autre part. Dans mon fichier main.cpp, j'inclus le fichier point.hpp. Si je retire l'inclusion, ça compile.
    Il faut que tu fasses l'inverse de ce qui t'as été dit. Dans circular_dll tu n'as pas besoin de la définition de point (apparemment tu n'as que des pointeurs sur point).

    Donc dans circular_dll.hpp tu mets

    class Point;

    et dans Point.hpp tu mets le #include "circular_dll.hpp"

  5. #5
    Membre régulier Avatar de Nadd
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 160
    Points : 95
    Points
    95
    Par défaut
    Dans la classe circular_dll, les pointeurs sur point sont utilisés, et donc la définition est nécessaire.

    J'obtiens l'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    use of undefined type 'point'

  6. #6
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Bonjour.

    LinuxUser a raison, il faut que tu mettes ton code dans les fichiers sources (.cpp). Les en-têtes (fichiers .hpp) ne doivent contenir que les déclarations.
    Un conseil, lis attentivement cette faq.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  7. #7
    Membre régulier Avatar de Nadd
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 160
    Points : 95
    Points
    95
    Par défaut
    Merci pour votre réponse.

    En réalité, c'était pour profiter de la déclaration implicite inline des méthodes de mes classes. J'ai donc tout séparé, en déclarant explicitement les méthodes inline et appliqué l'astuce de la FAQ.

    Par ailleurs, j'obtiens plusieurs erreurs d'un même genre. En voici un exemple :
    Error 1 error LNK2019: unresolved external symbol "public: double __thiscall point:: x(void)const " (?x@point@@QBENXZ) referenced in function "double __cdecl compute_origin_and_radius(class std::vector<class point *,class std::allocator<class point *> > const &,class point &)" (?compute_origin_and_radius@@YANABV?$vector@PAVpoint@@V?$allocator@PAVpoint@@@std@@@std@@AAVpoint@@@Z)
    point.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    inline void point::x(double x)
    {
    	_x = x;
    }
    opc.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
    16
    17
    18
    #ifndef OPC_H_INCLUDED
    #define OPC_H_INCLUDED
     
    #include <GL/glfw.h>
    #include <cstdlib>
    #include <math.h>
    #include <iostream>
    #include <vector>
     
    #include <Magick++.h>
     
    #include "triangle.hpp"
    #include "point.hpp"
    #include "mathlib.hpp"
     
    ...
     
    double compute_origin_and_radius(const vector<point*> & vertices, point & origin);
    opc.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    double compute_origin_and_radius(const vector<point*> & vertices, point & origin)
    {
    ...
    double xorigin = origin->x();
    }
    triangle.hpp et mathlib.hpp incluent tous les deux point.hpp.

    EDIT : J'ai oublié de préciser que quand la mention inline est retirée, l'erreur disparaît.

    Par contre, je n'ai pas encore eu le temps de séparer l'implémentation de la classe triangle de son fichier d'en-tête; je ne sais pas si ça peut jouer.

    Merci encore pour votre aide.

    Nicolas.

  8. #8
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Si ça compile quand il n'y a pas le mot-clé inline, c'est que le problème doit être de ce côté. Je te conseilles de jeter un coup d'oeil à la faq sur les fonctions inlines. Une inspiration me dit que celle-ci, en particulier, devrait t'aider
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  9. #9
    Membre confirmé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Points : 616
    Points
    616
    Par défaut
    Il faut déplacer tes fonctions inline comme éxpliqué ici
    http://stackoverflow.com/questions/6...endencies-in-c

    Regarde le message de epatel datant du Mar 10 '09 at 0:18.

  10. #10
    Membre régulier Avatar de Nadd
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 160
    Points : 95
    Points
    95
    Par défaut
    Ça fonctionne !

    Il s'agissait bien de placer les fonctions inline dans le fichier d'en-tête, après la définition de la classe.

    Merci à vous tous pour vos réponses.

    Nicolas.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 01/03/2009, 00h58
  2. Réponses: 4
    Dernier message: 31/03/2008, 15h07
  3. Problème d'inclusion de fichiers
    Par _Michel dans le forum C
    Réponses: 1
    Dernier message: 15/03/2008, 18h18
  4. Problème d'inclusion de fichiers
    Par VenusX117 dans le forum C
    Réponses: 8
    Dernier message: 22/10/2006, 12h58
  5. Problème d'inclusion de fichiers
    Par navis84 dans le forum Langage
    Réponses: 3
    Dernier message: 29/08/2006, 15h24

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