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

Bibliothèques C++ Discussion :

Linker error ?


Sujet :

Bibliothèques C++

  1. #1
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    308
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 308
    Points : 90
    Points
    90
    Par défaut Linker error ?
    Bonjour,

    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
    #include <cstdlib>
    #include <iostream>
     
    using namespace std;
     
    void fonc(char *k, char *j);
     
    int main(int argc, char *argv[])
    {
        char a[10];
        char b[10];
     
        cout << "Entrer a: " << endl;
        cin >> a;
        cout << "Entrer b: " << endl;
        cin >> b;
     
        fonc(a,b);
     
        system("PAUSE");
        return EXIT_SUCCESS;
    }
     
     
    void fonc(char *k , int *j)
    {
         cout << "Le premier est egal a: " << k << endl;
         cout << "Le deuxieme est egal a: " << j << endl;
    }
    Qu'est que c'est: " [Linker error] undefined reference to `fonc(char*, char*)' " ?

  2. #2
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    il y a une différence entre char* et int* Donc ça passe pas.

    La meilleure solution, c'est quand même de passer par les std::string du standard C++ !

    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
     
    #include <string>
    #include <iostream>
     
    using namespace std;
     
    void fonc(const std::string& k, const std::string& j);
     
    int main(int argc, char *argv[])
    {
        std::string a;
        std::string b;
     
        cout << "Entrer a: " << endl;
        cin >> a;
        cout << "Entrer b: " << endl;
        cin >> b;
     
        fonc(a,b);
     
        system("PAUSE");
        return EXIT_SUCCESS;
    }
     
     
    void fonc(const std::string& k, const std::string& j)
    {
         cout << "Le premier est egal a: " << k << endl;
         cout << "Le deuxieme est egal a: " << j << endl;
    }

  3. #3
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    308
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 308
    Points : 90
    Points
    90
    Par défaut
    Merci.

  4. #4
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    pense au !

  5. #5
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    308
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 308
    Points : 90
    Points
    90
    Par défaut
    A quoi sert le const ?
    Aussi, c'est quoi undefined reference?

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Le const indique que le paramètre ne sera pas modifié dans la fonction. Il est important de mettre le qualificatif const quand on ne va pas modifier les paramètres d'une méthode. Cela renforce la qualité du code; et je crois que certain compilateur l'utilise pour optimiser le code générer.

  7. #7
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    308
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 308
    Points : 90
    Points
    90
    Par défaut
    Pouvez vous m'indiquer le problème dans cette classe?
    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
    31
    32
    33
    34
     
     
    #include <iostream>
    using namespace std;
     
    class UneCitation
    {
       std::string Auteur; std::string Contenu;
    	public:
    		// class constructor
    		UneCitation(const std::string& sonAuteur, const std::string& sonContenu);
    		// class destructor
    		~UneCitation();
    		// method
    		void presenteToi();
    };
     
     
    // class constructor
    UneCitation::UneCitation(const std::string& sonAuteur, const std::string& sonContenu)
    {
    	strcpy(Auteur, sonAuteur);
    	strcpy(Contenu, sonContenu);
    }
     
    // class destructor
    UneCitation::~UneCitation()
    {}
     
    // class method
    void UneCitation::presenteToi()
    {
       cout << "L'auteur est: " << Auteur << "Le contenu est: " << Contenu << endl;
    }

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    1/Pour copier un std::string vers un autre, strcpy ne fonctionne pas. Il faut utiliser .... l'opérateur '='
    2/ Si ton destructeur ne fait rien, ne le déclare pas, le compilateur va en créer un par défaut qui ira très bien.
    3/ presenteToi ne modifie pas l'instance de l'objet sur laquelle elle s'applique : donc autant la déclarer en const (c'est possible aussi pour les méthodes).
    4/ Evites les using namespace surtout dans les .h.
    5/ Mets une déclaration de variable par ligne
    6/ Tu as besoin de <string> pour les chaînes et <iostream> pour les flux.
    Cela donne :
    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
    #include <string>
    //déclaration :
    class UneCitation
    {
    private:
       std::string Auteur;  // Remarque 5
       std::string Contenu;
    public:
    		// class constructor
    		UneCitation(const std::string& sonAuteur, const std::string& sonContenu);
    		// method
    		void presenteToi()const; // Remarque 3
    };
     
    #include <iostream>
     // Définition :
    // class constructor
    UneCitation::UneCitation(const std::string& sonAuteur, const std::string& sonContenu)
    {
    // Remarque 1:
    	Auteur = sonAuteur;
    	Contenu = sonContenu;
    }
     
    // class method
    void UneCitation::presenteToi() const
    {
       std::cout << "L'auteur est: " << Auteur << "Le contenu est: " << Contenu << std::endl;
    
    }
    On peut encore améliorer le constructeur en utilisant une liste d'initialisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    UneCitation::UneCitation(const std::string& sonAuteur, const std::string& sonContenu)
    :Auteur(sonAuteur),Contenu(sonContenu)
    {
    }
    Il est préférable d'utiliser cette forme quand cela est possible car on initialise directement la variable.
    Dans la forme précédente :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    UneCitation::UneCitation(const std::string& sonAuteur, const std::string& sonContenu)
    {
    	Auteur = sonAuteur;
    	Contenu = sonContenu;
    }
    Cela nécessite d'initialiser chacun des membres à une valeur par défaut, puis à appeler l'opérateur= pour changer le contenu. On fait donc trop de chose pour rien.

  9. #9
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    308
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 308
    Points : 90
    Points
    90
    Par défaut
    Je crois que je n'ai pas compris la dernière remarque.
    quelle différence y a-t-il entre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    :Auteur(sonAuteur), Contenu(sonContenu)
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Auteur = sonAuteur;
    Contenu = sonContenu;
    ?
    Auteur et Contenu ont été déclarés dans le privé donc ils sont initialisés aléatoirement dans les deux cas.

  10. #10
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    le premier cas, c'est la liste d'initialisation. C'est une bonne habitude que de l'utiliser au maximum.
    Après, du point de vue résultat, c'est la même chose. C'est juste 2 manières différentes de procéder.
    Au passage, certaines initialisations de variables membres ne peuvent se faire que par la liste d'initialisation : références, appel de classe mère, etc...

  11. #11
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    308
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 308
    Points : 90
    Points
    90
    Par défaut
    Merci beaucoup

  12. #12
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    308
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 308
    Points : 90
    Points
    90
    Par défaut
    Maintenant undefined reference to UneCitation::presenteToi().
    Mon projet est réparti sur 3 fichiers. J'ai mis dans main.ccp et dans unecitation.cpp include "unecitation.h". J'ignore de qu'elle référence il parle!

  13. #13
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par poukill Voir le message
    Après, du point de vue résultat, c'est la même chose.
    Désolé de chipoter, mais il me semble que ce n'est pas tout à fait la même chose : avec une liste d'initialisation, il y a un appel au constructeur idoine. Dans l'autre cas, il y a un appel à un constructeur par défaut puis à l'opérateur d'affectation. Outre que cela fait 2 opérations au lieu d'une, cela implique que le membre aie un constructeur par défaut et supporte l'affectation.

    Citation Envoyé par yo_haha Voir le message
    Maintenant undefined reference to UneCitation::presenteToi().
    Mon projet est réparti sur 3 fichiers. J'ai mis dans main.ccp et dans unecitation.cpp include "unecitation.h". J'ignore de qu'elle référence il parle!
    C'est probablement une erreur de link ? As-tu mis l'ensemble des .cpp dans ton projet ? Sont-ils tous compilés ?

  14. #14
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Désolé de chipoter, mais il me semble que ce n'est pas tout à fait la même chose : avec une liste d'initialisation, il y a un appel au constructeur idoine. Dans l'autre cas, il y a un appel à un constructeur par défaut puis à l'opérateur d'affectation. Outre que cela fait 2 opérations au lieu d'une, cela implique que le membre aie un constructeur par défaut et supporte l'affectation.
    C'est vrai, c'était juste une simplification de ma part. J'aurai peut-être pas du, mais étant donné que le posteur débute vraiment... j'ai penser que ça l'embrouillerait.

  15. #15
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    308
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 308
    Points : 90
    Points
    90
    Par défaut
    Deux .cpp et un .h. Ils sont tous compliés.

  16. #16
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 371
    Points : 23 626
    Points
    23 626
    Par défaut
    Citation Envoyé par yo_haha Voir le message
    Aussi, c'est quoi undefined reference?
    Comme je n'ai pas vu la réponse, je la donne :

    « Undefined Reference », ça veut dire « référence indéfinie » et cela signifie que ton code fait appel à une fonction ou un objet qui n'est défini nulle part.

    Au stade de la compilation, le compilateur se dit « bon, très bien, compilons quand même, on fera la relation entre les deux à la fin, quand tout sera construit ». Si, à ce moment-là, l'entité en question n'est toujours pas définie, l'éditeur de liens ne peut pas aller plus loin et te répond en substance : « ça, moi, connais pas ».

    Cela arrive donc dans au moins trois cas : soit tu as fait une faute de frappe sur le nom de cet objet, soit il fait partie d'une bibliothèque que tu as omis de lier, soit la signature n'est pas la bonne, c'est-à-dire que la fonction concernée n'est pas utilisable avec le type de données que tu lui passes en argument.

  17. #17
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    308
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 308
    Points : 90
    Points
    90
    Par défaut
    D'accord. Merci... Les choses sont un peu plus claires! Mon cas c'est le troisième je crois.

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

Discussions similaires

  1. [Qt4] Linker error (vtable)
    Par titus55 dans le forum Qt
    Réponses: 7
    Dernier message: 23/05/2007, 10h04
  2. [Linker error] undefined reference to 'IcmpSendEcho@'
    Par Xevious dans le forum Autres éditeurs
    Réponses: 7
    Dernier message: 29/12/2005, 16h45
  3. Réponses: 17
    Dernier message: 25/10/2005, 10h09
  4. Linker error :^/
    Par Ekinoks dans le forum OpenGL
    Réponses: 15
    Dernier message: 05/09/2004, 14h18
  5. [Kylix] probleme (LINKER ERROR)
    Par subzero82 dans le forum EDI
    Réponses: 2
    Dernier message: 14/05/2004, 19h28

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