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 :

Reference indéfini vers ..


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Invalidité
    Inscrit en
    mai 2019
    Messages
    150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Invalidité

    Informations forums :
    Inscription : mai 2019
    Messages : 150
    Points : 31
    Points
    31
    Par défaut Reference indéfini vers ..
    Bonjour ,

    Lorsque je compile , il me reste 2 erreurs que je n'arrive pas a solutionner .

    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
    #ifndef PERSONNE_HPP_
    #define PERSONNE_HPP_
     
    #include <string>
     
    class Personne
    {
      private:
      std::string nom;
      std::string prenom;
      int age;
     
      public:
      Personne();
      void afficher();
      std::string get_nom();
      std::string get_prenom();
      int get_age();
     
      void set_nom(std::string a);
      void set_prenom(std::string b);
      void set_age(int c);
     
    };
     
    #endif /* PERSONNE_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
    #include "personne.h"
    #include <iostream>
    #include <string>
     
     
    std::string nom,prenom;
    int age;
     
    Personne::Personne()
    {
    	nom = "";
    	prenom = "";
    	age=0;
    }
     
    void Personne::afficher()
    {
    	std::cout << "Nom: " << nom << std::endl;
    	std::cout << "prenom: " << prenom << std::endl;
    	std::cout << "Age: " << age << std::endl;
    }
     
    std::string get_nom(){return nom;}
    std::string get_prenom(){return prenom;}
    int get_age(){return age;}
     
    void set_nom(std::string a){nom = a;}
    void set_prenom(std::string b){prenom = b;}
    void set_age(int c){age = 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
    #include "personne.h"
    #include <iostream>
    #include <string>
    using namespace std;
     
    int main()
    {
     Personne chris;
     string a,b;
     int c;
     cout << "Entrez nom famille:" << endl;
     cin >> a;
     chris.set_nom(a);
     cin.ignore();
     cout << "Entrez prenom: " << endl;
     cin >>b;
     chris.set_prenom(b);
     cin.ignore();
     cout << "Entrez age: " << endl;
     cin >>c;
     chris.set_age(c);
     cin.ignore();
     
     chris.afficher();
     
     return 0;
    }
    Et donc j'ai ces 2 erreurs :

    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
    18:17:19 **** Incremental Build of configuration Debug for project personne ****
    make all 
    Building target: personne
    Invoking: GCC C++ Linker
    g++  -o "personne"  ./main.o ./personne.o   
    ./main.o*: Dans la fonction «*main*»*:
    /home/chris/Projets_C++/personne/Debug/../main.cpp:13*: référence indéfinie vers «*Personne::set_nom(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)*»
    /home/chris/Projets_C++/personne/Debug/../main.cpp:17*: référence indéfinie vers «*Personne::set_prenom(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)*»
    /home/chris/Projets_C++/personne/Debug/../main.cpp:21*: référence indéfinie vers «*Personne::set_age(int)*»
    makefile:44: recipe for target 'personne' failed
    collect2: error: ld returned 1 exit status
    make: *** [personne] Error 1
    "make all" terminated with exit code 2. Build might be incomplete.
     
    18:17:20 Build Failed. 2 errors, 0 warnings. (took 745ms)
    Merci de votre aide .

  2. #2
    Membre habitué Avatar de BioKore
    Homme Profil pro
    .
    Inscrit en
    septembre 2016
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : septembre 2016
    Messages : 274
    Points : 198
    Points
    198
    Par défaut
    Bonjour,

    Je n'ai pas testé le code mais plusieurs choses m'interpellent ici. Dans un premier temps, pourquoi, dans ton *.cpp de ta classe, tu re-inclus std::string ? Compte tenu du fait qu'il est déjà dans le *.hpp et que ce dernier est inclus dans le *.cpp, il est ici inutile. Cependant, c'est juste un sujet mineur ; ceci n'engendrera aucun bug.
    Dans la même lignée, pourquoi utiliser des #ifndef ... #define ... #endif ? Remplace tout ça par un simple #pragma once et ça ira bien. Mais là aussi, c'est juste de la mise en forme.
    Chose plus important par contre, toujours dan ton *.cpp, pourquoi diantre re-déclarer "nom, prénom et age" ??? Ces éléments sont des variables membres de ta classe, ils n'ont rien à faire en global dans ton *.cpp !!

    Aussi, préfère les listes d'initialisation pour tes constructeurs.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // a ne pas faire !
    Personne::Personne()
    {
    	nom = "";
    	prenom = "";
    	age=0;
    }
     
    // c'est mieux comme ça !
    Personne:Personne():
    	nom{},
    	prenom{},
    	age{} {}

    Concernant la classe. Cette dernière est "inutile" dans le sens où les méthodes n'ont ici pour but que de modifier tous les membres. Ici, j'aurais simplement créé une structure du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct Personne {
    	std::string nom{};
    	std::string prenom{};
    	unsigned short int age{};	//255 est en général suffisant pour un age...
    };
    Préfère une approche procédurale lorsque possible. C'est bien souvent suffisant et plus simple à mettre en œuvre.

    Aussi, évite d'utiliser les using namespace std; ça t'évitera bien des soucis par la suite...

    Et dernier point, les références indéfinies sont souvent liées à une problématique de compilation. A voir quelles sont tes options de compilation mais il faut que tu appelles tous tes *.cpp. Par exemple : make -o test *.cpp -W -Wextra --std=c++14Tiens nous au courant de tes avancées.

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    juin 2010
    Messages
    6 588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 6 588
    Points : 30 113
    Points
    30 113
    Billets dans le blog
    4
    Par défaut
    - tes fonctions set_nom etc ne sont pas implémentées dans la classe
    - seuls le constructeur et afficher le sont
    - tu déclares des globales dans personne.cpp
    - tu n'as aucune const-correctness
    - std::string s'initialise par défaut à une chaîne vide
    - using namespace std; est à bannir
    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.

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Invalidité
    Inscrit en
    mai 2019
    Messages
    150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Invalidité

    Informations forums :
    Inscription : mai 2019
    Messages : 150
    Points : 31
    Points
    31
    Par défaut
    Merci a tous les deux .
    Vous me dites de ne pas redeclarer mes variables nom, penom et age dans le .cpp mais , ne faut il pas respecter le principe d'encapsulation des données et accéder à celles-ci au travers des assesseurs ? ou je m'embrouille un peu ...
    J'ai implémenté les méthodes comme tu me l'a dit dans mon .cpp et apres reflexion , je viens de m'apercevoir que pour mes methodes get et set , il me manque aussi la référence à la classe et c'est peu etre pour ca que ca compile pas .
    Daccord pour ne pas utiliser using namespace std dans le header mais meme dans les autres fichier , je dois m'en abstenir ?

  5. #5
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2011
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : juin 2011
    Messages : 677
    Points : 3 284
    Points
    3 284
    Par défaut
    ne faut il pas respecter le principe d'encapsulation des données et accéder à celles-ci au travers des assesseurs ?
    Où est l'encapsulation lorsque tous les membres privées ont des fonctions pour les y accéder et les modifier ? L'interface d'une classe se réfléchit en termes de service: ce qu'elle devrait faire, et non pas à comment elle devrait le faire. Une classe qui expose intensivement des accesseurs n'est rien de plus qu'un aggloméra de donnée: elle n'expose aucun service, autant tout mettre en public.

    Daccord pour ne pas utiliser using namespace std dans le header mais meme dans les autres fichiers , je dois m'en abstenir ?
    Dans les .cpp ce n'est pas très grave, cela ne se propage pas aux autres fichiers. Mais il y a toujours des risques de conflit de nom avec un using namespace. Personnellement, je m’abstiens, surtout que je trouve plus clair de toujours préfixer par le namespace std::.

  6. #6
    Membre habitué Avatar de BioKore
    Homme Profil pro
    .
    Inscrit en
    septembre 2016
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : septembre 2016
    Messages : 274
    Points : 198
    Points
    198
    Par défaut
    Alors les using namespace ne sont surtout pas à mettre dans les hpp. La bonne pratique est de ne pas du tout les utiliser, mais si, pour une raison x ou y tu le fais en pleine conscience des impacts, c'est à mettre dans le cpp uniquement ; jamais dans les headers.

    En ce qui concerne les "setters" et "getters", il s'agit de fonctions et non de variables.
    Dans ton cas, les setters sont void set_nom(std::string const & val); etc... et les getters std::string const & get_nom() const; etc... En aucun cas il ne s'agit de variables globales !

    Bref, je t'invite à suivre un cours sur la programmation. Je laisse le soin aux personnes compétentes de ce forum pour te guider vers des ouvrages ou tout autre ressources pertinentes à ce sujet. Il est important de partir avec de bonnes bases. Tâche de ne pas "rusher" ces dernières.
    Selon moi, quelque soit ta méthode d'apprentissage, dans tous les cas, tâche de toujours réaliser un code propre, lisible, constant dans sa mise en forme. Ces quelques principes, appuyés par l'expertise des membres de ce forum, m'ont permis de prendre une belle maturité et assurance dans l'écriture de mes sources.

    Bon courage !

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Invalidité
    Inscrit en
    mai 2019
    Messages
    150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Invalidité

    Informations forums :
    Inscription : mai 2019
    Messages : 150
    Points : 31
    Points
    31
    Par défaut
    Je vous remercie de vos conseils et de vos encouragements .

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 08/03/2010, 18h00
  2. référence indéfinie vers « vtable for FenPrincipale
    Par yLaplace dans le forum Débuter
    Réponses: 5
    Dernier message: 01/03/2010, 14h49
  3. reference indefinie vers
    Par psylox dans le forum C
    Réponses: 12
    Dernier message: 30/04/2007, 16h15
  4. Réponses: 2
    Dernier message: 28/02/2007, 04h39
  5. Réponses: 10
    Dernier message: 02/01/2007, 13h07

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