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 :

Problème dans un constructeur


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2008
    Messages : 49
    Par défaut Problème dans un constructeur
    Bien, alors, j'aimerais bien trouver moi-même où est l'erreur, mais je n'y arrive pas... Et malgré les heures passées à écrire du code, j'ai toujours l'impression d'être au niveau débutant!

    J'ai une classe Hexagon qui contient un pointeur vers une classe YPiece. Une YPiece contient deux Hexagon.

    Voilà la déclaration de Hexagon:
    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
    #include <vector>
    #include <boost/array.hpp>
    #include "PointMat.h"
    class YPiece;
     
    typedef boost::array<double,6> DoubleArray6;
     
    class Hexagon{
     
    private:
    	int m_Index;
    	const YPiece*  m_YPce;
    	DoubleArray6 m_Lengths;
    	std::vector<PointMatH> m_Vertices;
     
    public:
    	inline Hexagon(const Hexagon& p_Hex);
    	Hexagon(int, const YPiece*, const double, const double, const double);
    };
    le cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include "Hexagon.h"
    #include "YPiece.h"
    inline Hexagon::Hexagon(const Hexagon& p_Hex):
    	m_Index(p_Hex.m_Index), m_YPce(p_Hex.m_YPce), m_Lengths(p_Hex.m_Lengths), m_Vertices(p_Hex.m_Vertices){};
    Hexagon::Hexagon(int p_Index, const YPiece* p_YPce, const double p_L1, const double p_L3, const double p_L5):
    	m_Index(p_Index),m_YPce(p_YPce){
    ...}
    Voilà celle de YPiece:
    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
    #include <string>
    #include <vector>
    #include "Hexagon.h"
    #include "Collar.h"
    typedef std::vector<Collar*> CollarArray;
     
    class YPiece{
    private:
    	std::string m_Name;
    	Hexagon m_Hex1;
    	Hexagon m_Hex2;
     
    public:
    	CollarArray m_Collars;
     
    	YPiece(const std::string& p_Name):m_Name(p_Name){m_Collars.reserve(3);};
    	YPiece(const YPiece& p_YPce): m_Name(p_YPce.m_Name),m_Hex1(p_YPce.m_Hex1),m_Hex2(p_YPce.m_Hex2),m_Collars(p_YPce.m_Collars){};
     
    	void SetYPieceHexagons(){};
    le cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include "YPiece.h"
    #include "Hexagon.h"
    void YPiece::SetYPieceHexagons(){
    	double l_Length1((m_Collars.at(0)->GetLength())/2);
    	double l_Length3((m_Collars.at(1)->GetLength())/2);
    	double l_Length5((m_Collars.at(2)->GetLength())/2);
    	Hexagon H1(1, this, l_Length1, l_Length3, l_Length5);
    	Hexagon H2(2, this, l_Length1, l_Length3, l_Length5);
    }
    C'est le "this" de SetYPieceHexagons() qui pose problème, je crois... Le but est d'en faire le pointeur m_YPce dont Hexagon a besoin.
    Si quelqu'un a une idée...

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 162
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 162
    Billets dans le blog
    153
    Par défaut
    Bonjour,

    Quel est le message d'erreur renvoyé par le compilateur ?

    Avez vous bien mis les include nécessaire (notamment celui du Hexagon pour le fichier YPiece.hpp) ?
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2008
    Messages : 49
    Par défaut
    Bonjour, merci pour la réponse... Mon message était effectivement mal écrit, j'avais essayé de condenser en mettant directement dans la déclaration de la classe le constructeur de Hexagon et la fonction SetYPieceHexagons... J'ai modifié maintenant. Concernant les include, je crois que ça devrait marcher comme ça...

    Le début du message d'erreur est celui-là:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Undefined symbols:
      "PointD::DistanceTo(PointD const&) const", referenced from:
          Hexagon::Hexagon(int, YPiece const*, double, double, double)in Hexagon.o
          Hexagon::Hexagon(int, YPiece const*, double, double, double)in Hexagon.o
    C'est le genre de message que j'ai toujours du mal à comprendre parce que l'erreur n'est jamais indiquée à la ligne posant problème. Si ça se trouve, l'erreur n'est pas celle à laquelle je pense!

    J'imagine les sourires se dessinant sur vos visages...

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 162
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 162
    Billets dans le blog
    153
    Par défaut
    Le compilateur dit qu'il ne trouve pas la fonction DistanceTo qui doit être dans la classe Point.
    Moi, lorsque j'ai cette erreur, c'est que j'ai oublié de mettre le "Point::" lors de la définition de la méthode dans le .cpp de Point.
    Genre, actuellement vous avez :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void DistanceTo(...)
    {
    ...
    }
    Alors que cela devrait être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void Point::DistanceTo(...)
    {
    ...
    }
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2008
    Messages : 49
    Par défaut
    En fait, si jamais, le "tu" ne me dérange pas bien au contraire!

    La fonction DistanceTo en question, je l'ai déclarée dans le header PointD.h, par contre, je ne l'ai pas encore implémentée... Mais cela ne devrait pas poser de problème, non?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #include <complex>
    typedef std::complex<double> Complex;
    class PointD{
    private:
    	Complex m_Z;
     
    public:
    	PointD(double p_x, double p_y):m_Z(p_x,p_y){};
     
    	const Complex& GetZ() const {return m_Z;};
     
    	double DistanceTo(const PointD&) const;
    };
    Je remets aussi le message d'erreur en entier, ce sera peut-être plus utile (je pensais que l'erreur n'était liée qu'à ce constructeur d'Hexagon qui prenait un this en argument):
    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
     
    Building target: HG_Triangulation2
    Invoking: MacOS X C++ Linker
    g++  -o "HG_Triangulation2"  ./Collar.o ./Hexagon.o ./PointD.o ./PolygonD.o ./Surface.o ./YPiece.o ./main.o   
    Undefined symbols:
      "PointD::DistanceTo(PointD const&) const", referenced from:
          Hexagon::Hexagon(int, YPiece const*, double, double, double)in Hexagon.o
          Hexagon::Hexagon(int, YPiece const*, double, double, double)in Hexagon.o
      "YPiece::YPiece(YPiece const&)", referenced from:
          std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, YPiece>::pair(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, YPiece const&)in Surface.o
          std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, YPiece>::pair(std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, YPiece> const&)in Surface.o
      "YPiece::YPiece(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)", referenced from:
          Surface::Surface(__gnu_cxx::__normal_iterator<Collar*, std::vector<Collar, std::allocator<Collar> > >, __gnu_cxx::__normal_iterator<Collar*, std::vector<Collar, std::allocator<Collar> > >)in Surface.o
          Surface::Surface(__gnu_cxx::__normal_iterator<Collar*, std::vector<Collar, std::allocator<Collar> > >, __gnu_cxx::__normal_iterator<Collar*, std::vector<Collar, std::allocator<Collar> > >)in Surface.o
      "PointMatH::PointMatH(PointD const&)", referenced from:
          Hexagon::Hexagon(int, YPiece const*, double, double, double)in Hexagon.o
          Hexagon::Hexagon(int, YPiece const*, double, double, double)in Hexagon.o
    ld: symbol(s) not found
    collect2: ld returned 1 exit status
    make: *** [HG_Triangulation2] Error 1
    (la partie du milieu, je ne comprends pas du tout...)

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 154
    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 154
    Billets dans le blog
    4
    Par défaut
    Et bien si, une fonction non implémentée qu'on essaye d'utiliser, le linker perd la boule.
    Il t'indique justement qu'il la trouve pas, à juste titre.


    Imagine-toi partir en vacances, ton pote te dit qu'il a la voiture; ça c'est le header, qui indique ce qui existe (en théorie - tout n'est pas forcément implémenté encore)
    Venu le moment du départ (le linker), s'il n'a pas apporté la voiture, t'es dans la merde ; ce qui existe, si on souhaite l'utiliser, doit être défini
    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.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2008
    Messages : 49
    Par défaut
    Eh ben, voilà, tout les livres de c++ devraient être écrits comme ça!

    Bon, effectivement, j'utilise cette fonction DistanceTo pour faire un test if() sur la distance entre deux points. Mais je pensais que le fait de lui avoir dit qu'elle existait et qu'elle renvoyait un double suffisait pour ne pas générer d'erreur à la compilation!

  8. #8
    Membre émérite
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Par défaut
    Justement, il ne génère pas d'erreur à la compilation à proprement parler, mais au link.
    C'est visible par le fait que les fichiers envoyés à gcc finissent en .o.

    En résumé :
    .cpp -> .o : compilation
    .o + .o + .o -> exécutable : link

    Et, au moment où il link, il ne s'attend pas à trouver une fonction manquante : c'est justement là qu'il fait le lien entre les fonctions utilisées et les définies.

    Un exemple valant plus que mille mots :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // Code du 1er fichier :
    void bar() { ++i; }
    // Compilation
    bar(): ++i // Assembleur sur-simplifié.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // Code du 2nd fichier :
    void bar();
    void foo() { bar(); }
    // Compilation :
    foo(): call bar() // Assembleur sur-simplifié. Le point important est qu'on *ne connait pas* le code de bar, mais ce n'est pas important pour le moment
    Puis arrive le linker, qui va mettre ensemble les deux fichiers :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    bar(): ++i
    foo(): call bar()
    Ici, tout va bien : le linker connait toutes les fonctions utilisées.

    Maintenant, un exemple qui ne marche pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // Code du seul fichier :
    void bar();
    void foo() { bar(); }
    // Compilation :
    foo(): call bar() // Assembleur sur-simplifié. Le point important est qu'on *ne connait pas* le code de bar, mais ce n'est pas important pour le moment
    Puis arrive le linker, qui va mettre ensemble les deux fichiers ... Euh, pardon, le seul fichier :
    Et là, il va tenter de savoir ce qu'est bar() ; pour pouvoir déterminer quel exécutable donner.
    C'est la catastrophe ! Il a beau chercher, il ne trouve pas bar() !
    Donc il te crache ce message d'erreur, et annonce qu'il n'est pas capable de faire son travail.

    D'où l'erreur du linker.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2008
    Messages : 49
    Par défaut
    ok! C'est marrant, parce que ma réaction était de résoudre le problème avant de continuer, alors que la solution était justement de poursuivre!

    Merci beaucoup!

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2008
    Messages : 49
    Par défaut
    Ce n'est pas tout à fait fini, mais vous m'avez ouvert les yeux... J'ai changé le code (cf premier message), et j'ai encore cette erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Undefined symbols:
      "Hexagon::Hexagon(Hexagon const&)", referenced from:
          YPiece::YPiece(YPiece const&)in Surface.o
          YPiece::YPiece(YPiece const&)in Surface.o
    Alors, je comprends bien ce qu'il veut dire, il ne trouve pas le constructeur par copie de Hexagon. Pourtant il existe, mais je l'ai déclaré inline. Je ne pouvais pas l'écrire directement inline dans Hexagon.h puisque je ne pouvais pas y mettre "#include YPiece.h" à cause des références croisées entre les classes Hexagon et YPiece.

    Il y a effectivement à la compilation un warning:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    inline function 'Hexagon::Hexagon(const Hexagon&)' used but never defined
    qui engendre l'erreur pour le linker (si je vous ai bien suivi). Ce warning lié au mot "inline", je l'ai souvent vu... Pourquoi ne reconnait-il pas la fonction dans le cpp????

  11. #11
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 154
    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 154
    Billets dans le blog
    4
    Par défaut
    Je suis pas 100% sur, mais il me semble que le inline n'a rien à faire dans le .cpp
    Il ne doit apparaître que dans le prototype.
    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.

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2008
    Messages : 49
    Par défaut
    Oui, c'est bon, j'ai résolu le problème en fait!
    Merci à tous!

  13. #13
    Membre émérite
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Par défaut
    Le inline ne doit en effet pas apparaître dans le cpp, mais il y a quand même possibilité de s'en sortir comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //a.hpp
    #ifndef A_
    #define A_
    #include "b.hpp"
    class A { B b; };
    #endif
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    //b.hpp
    #ifndef B_
    #define B_
    class A;
    class B { A * a; inline B(); };
    #include "a.hpp" // Ici est toute l'astuce : on inclut après avoir défini la classe, puis on définit le inline
    inline B::B() { a = new A; }
    #endif
    Mais il ne faut jamais mettre de inline dans un .cpp ! (sauf si on n'utilise ce inline que dans le .cpp, bien sûr)

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 23/01/2012, 17h34
  2. Problème d'allocation mémoire dans un constructeur
    Par zaz83 dans le forum Débuter
    Réponses: 2
    Dernier message: 12/06/2009, 13h31
  3. Réponses: 13
    Dernier message: 31/10/2008, 13h32
  4. problème dans le constructeur
    Par hamoudasafira dans le forum C++
    Réponses: 5
    Dernier message: 11/04/2007, 18h20
  5. Réponses: 6
    Dernier message: 26/06/2006, 23h49

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