Précédent   Forum du club des développeurs et IT Pro > C et C++ > C++
C++ Forum d'entraide technique sur le langage C++. Avant de poster -> F.A.Q C++
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 30/12/2012, 13h23   #1
Evijn
Invité de passage
 
Homme Romain
Étudiant
Inscription : décembre 2012
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Romain
Âge : 22
Localisation : Belgique

Informations professionnelles :
Activité : Étudiant
Secteur : Industrie

Informations forums :
Inscription : décembre 2012
Messages : 8
Points : 2
Points : 2
Par défaut Souci association entre classes, erreur de linker

Bonjour à tous,

Tout d'abord je précise que je débute en c++.

J'essaye actuellement de faire un petit programme qui gère une bibliothèque (travail scolaire), et pour celà je dois avoir des auteurs qui sont des instances d'une classe Auteur qui elle-même hérite d'une classe Personne.

Mon code ressemble donc à cela :

Code :
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
 
 
// Auteur.h
 
#ifndef AUTEUR_H
#define AUTEUR_H
 
#include "Personne.h"
/*
 * No description
 */
class Auteur : public Personne
{
	public:
		// class constructor
		Auteur();
		Auteur(char* name[4]):Personne(name){}      // car les constructeurs d'initialisation ne sont jamais hérités
 
		//fonction membre
		char* getNom();
		void setNom(char* name[4]);
		void displayName(void);
 
		// class destructor
		~Auteur();
};
 
#endif // AUTEUR_H
Code :
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
35
36
37
38
39
40
41
42
43
44
45
46
 
 
// Auteur.cpp
 
#include <string.h>
#include <stream.h>
#include <iostream>
#include <cstring>
 
#include "auteur.h" // class's header file
 
// class constructor
Auteur::Auteur()
{
	// insert your code here
}
 
// fonctions membres
char* Auteur::getNom()
{
    for(int i=0 ; i<4 ; i++)
    return Nom[i]; 
}
 
void Auteur::displayName(void)
{
    cout << "Auteurs: " ;
    for(int i=0 ; i<4 ; i++)
        cout << Nom[i] << " ";
    cout << endl;
}
 
void Auteur::setNom(char* name[4])
{
    for(int i=0 ; i<4 ; i++)
    {
        Nom[i]= new char(strlen(name[i])+1);
        strcpy(Nom[i],name[i]);
    }
}
 
// class destructor
Auteur::~Auteur()
{
	// insert your code here
}
Code :
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
 
 
// Personne.h
 
#ifndef PERSONNE_H
#define PERSONNE_H
 
/*
 * No description
 */
class Personne
{
    protected:
        // je décide que l'on doit mettre 4 noms
        char* Nom[4];
 
	public:
		// class constructor
        Personne();
		Personne(char* name[4]);
		Personne(const Personne &pp);
 
		//fonction membre
		char* getNom();
		void setNom(char* name[4]);
        void displayName(void);
 
        // class destructor
		~Personne();
};
Code :
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
35
36
37
38
39
 
 
// Personne.cpp
 
#include <string.h>
#include "personne.h" // class's header file
 
// class constructor
Personne::Personne()
{
    for(int i=0 ; i<4 ; i++)
	Nom[i]=0;
}
Personne::Personne(char* name[4])       // constructeur d'initialisation
{
     for(int i=0 ; i<4 ; i++)
     {
         Nom[i]=new char[strlen(name[i])+1]; 
         strcpy(Nom[i], name[i]);
     }
}
Personne::Personne(const Personne &pp)
{
     for(int i=0 ; i<4 ; i++)
     {
         Nom[i] = new char[strlen(pp.Nom[i])+1];
         strcpy(Nom[i], pp.Nom[i]);
     }
}
 
// class destructor
Personne::~Personne()
{
     for(int i=0 ; i<4 ; i++)
     if (Nom[i]) 
     {
       delete Nom[i];
     }
}

Et voici une partie de ma fonction main en rapport avec tout ça :

Code :
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 <cstdlib>
#include <iostream>
 
#include "Auteur.h"              
 
using namespace std;
 
int main(int argc, char *argv[])
{   
 
   [...]
 
    Auteur a;
 
    char* name[4] = {"Oncle Bens" , "Oncle Picsou" , "Oncle Tom" , "Oncle Cloclo"};
    Personne pp (name);
 
    [...]
 
    // Affichage
 
    a.displayName(); 
 
    [...]
 
    system("PAUSE");
    return EXIT_SUCCESS;
}
Lors de la compilation, j'obtiens cette erreur:

[Linker error] undefined reference to `Personne::Nom'

Pourriez vous m'éclairer svp je cale complètement.
Un grand merci d'avance :D
Evijn est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2012, 13h52   #2
JolyLoic
Rédacteur/Modérateur
 
Avatar de JolyLoic
 
Homme Loïc Joly
Développeur informatique
Inscription : août 2004
Messages : 4 698
Détails du profil
Informations personnelles :
Nom : Homme Loïc Joly
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2004
Messages : 4 698
Points : 9 964
Points : 9 964
Je passerai sur le fait qu'une chaîne de caractères en C++, ce n'est pas un char*, mais un std::string ! Il y a des chances que la personne à blâmer ici soit ton professeur, et non pas toi...


Pour ton problème, peux-tu nous indiquer comment tu compiles ? Souvent, les erreurs de link sont plus liées à ça qu'à un problème dans le code lui-même.
__________________
Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
JolyLoic est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2012, 14h10   #3
Evijn
Invité de passage
 
Homme Romain
Étudiant
Inscription : décembre 2012
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Romain
Âge : 22
Localisation : Belgique

Informations professionnelles :
Activité : Étudiant
Secteur : Industrie

Informations forums :
Inscription : décembre 2012
Messages : 8
Points : 2
Points : 2
Merci de votre réponse rapide.

Dans le cadre du cours je dois utiliser le logiciel Dev C++, et je compile au travers de celui-ci
Evijn est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2012, 16h24   #4
JolyLoic
Rédacteur/Modérateur
 
Avatar de JolyLoic
 
Homme Loïc Joly
Développeur informatique
Inscription : août 2004
Messages : 4 698
Détails du profil
Informations personnelles :
Nom : Homme Loïc Joly
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2004
Messages : 4 698
Points : 9 964
Points : 9 964
Pourrais tu mettre le log de compilation, avec un peu de chance, on y verra des informations.
__________________
Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
JolyLoic est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2012, 17h18   #5
Evijn
Invité de passage
 
Homme Romain
Étudiant
Inscription : décembre 2012
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Romain
Âge : 22
Localisation : Belgique

Informations professionnelles :
Activité : Étudiant
Secteur : Industrie

Informations forums :
Inscription : décembre 2012
Messages : 8
Points : 2
Points : 2
Voici les logs de la compilation:

Code :
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
Compiler: Default compiler
Building Makefile: "G:\c++\Romain\TP2bis_Romain\Makefile.win"
Executing  make clean
rm -f main.o document.o documentpapier.o livre.o errisbn.o errbase.o errnbr.o errprix.o prixavectva.o outils.o sommeargent.o contentieux.o auteur.o personne.o  TP2bis.exe
 
g++.exe -c main.cpp -o main.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   
 
g++.exe -c document.cpp -o document.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   
 
In file included from C:/Dev-Cpp/include/c++/3.4.2/backward/stream.h:31,
                 from document.cpp:3:
C:/Dev-Cpp/include/c++/3.4.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
 
g++.exe -c documentpapier.cpp -o documentpapier.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   
 
In file included from C:/Dev-Cpp/include/c++/3.4.2/backward/stream.h:31,
                 from documentpapier.cpp:3:
C:/Dev-Cpp/include/c++/3.4.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
 
g++.exe -c livre.cpp -o livre.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   
 
In file included from C:/Dev-Cpp/include/c++/3.4.2/backward/stream.h:31,
                 from livre.cpp:4:
C:/Dev-Cpp/include/c++/3.4.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
 
g++.exe -c errisbn.cpp -o errisbn.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   
 
g++.exe -c errbase.cpp -o errbase.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   
 
g++.exe -c errnbr.cpp -o errnbr.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   
 
g++.exe -c errprix.cpp -o errprix.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   
 
g++.exe -c prixavectva.cpp -o prixavectva.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   
 
In file included from C:/Dev-Cpp/include/c++/3.4.2/backward/iostream.h:31,
                 from prixavectva.cpp:3:
C:/Dev-Cpp/include/c++/3.4.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
 
g++.exe -c outils.cpp -o outils.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   
 
In file included from C:/Dev-Cpp/include/c++/3.4.2/backward/iostream.h:31,
                 from outils.cpp:3:
C:/Dev-Cpp/include/c++/3.4.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
 
g++.exe -c sommeargent.cpp -o sommeargent.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   
 
g++.exe -c contentieux.cpp -o contentieux.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   
 
g++.exe -c auteur.cpp -o auteur.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   
 
In file included from C:/Dev-Cpp/include/c++/3.4.2/backward/stream.h:31,
                 from auteur.cpp:3:
C:/Dev-Cpp/include/c++/3.4.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
 
g++.exe -c personne.cpp -o personne.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   
 
g++.exe main.o document.o documentpapier.o livre.o errisbn.o errbase.o errnbr.o errprix.o prixavectva.o outils.o sommeargent.o contentieux.o auteur.o personne.o  -o "TP2bis.exe" -L"C:/Dev-Cpp/lib"  
 
auteur.o(.text+0x141):auteur.cpp: undefined reference to `Personne::Nom'
auteur.o(.text+0x17d):auteur.cpp: undefined reference to `Personne::Nom'
auteur.o(.text+0x203):auteur.cpp: undefined reference to `Personne::Nom'
auteur.o(.text+0x221):auteur.cpp: undefined reference to `Personne::Nom'
personne.o(.text+0x19):personne.cpp: undefined reference to `Personne::Nom'
personne.o(.text+0x43):personne.cpp: more undefined references to `Personne::Nom' follow
collect2: ld returned 1 exit status
 
make.exe: *** [TP2bis.exe] Error 1
 
Execution terminated
J’espère que ça pourra vous éclairer parce que je ne comprend pas mon erreur, j'ai encore regardé ça de plus près avec mon cours.

C'est surement un truc bête mais ce qui m'embête c'est que ça compile, et c'est au moment de l'édition des liens que ça provoque une erreur. Le logiciel ne peut donc pas me donner d'indication très précise sur mon erreur, d'où mon désarroi

Merci d'avance :-)
Evijn est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2012, 17h33   #6
JolyLoic
Rédacteur/Modérateur
 
Avatar de JolyLoic
 
Homme Loïc Joly
Développeur informatique
Inscription : août 2004
Messages : 4 698
Détails du profil
Informations personnelles :
Nom : Homme Loïc Joly
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2004
Messages : 4 698
Points : 9 964
Points : 9 964
Désolé, mais je ne vois rien de louche dans ce que je lis. Peut-être quelqu'un ayant plus l'habitude de gcc ?
__________________
Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
JolyLoic est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2012, 17h43   #7
zhouyu
Membre habitué
 
Avatar de zhouyu
 
Homme Loïc
Étudiant
Inscription : octobre 2009
Messages : 83
Détails du profil
Informations personnelles :
Nom : Homme Loïc
Âge : 25
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : octobre 2009
Messages : 83
Points : 129
Points : 129
Salut.
Je pense que l'erreur vient de ce code :
Code :
1
2
3
4
5
6
// fonctions membres
char* Auteur::getNom()
{
    for(int i=0 ; i<4 ; i++)
    return Nom[i]; 
}
Tu dois renvoyer un char * et tu renvoies un char, de plus la methode est fausse.
Ce que tu as écrit est : pour chaque i je renvoie le i ème caractère.
Cependant au premier return la fonction s’arrête. Tu renvoies toujours Nom[0].
Dans ton cas tu devrais avoir seulement :
Code :
1
2
3
4
5
 
char* Auteur::getNom()
{
    return Nom; 
}
Une lettre = un char, plusieurs lettres(mots) = char* ou string.
Un char* ou string est tout simplement un tableau de lettre.

EDIT : en faite tu n'as pas écrit toutes les méthodes de Personne.h dans Personne.cpp ... donc il ne peut pas faire la liaison.
Tu es déjà censé écrire une fonction getNom() dans Personne. Si dans auteur elle fait la même chose pas besoin d'en refaire une .
zhouyu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2012, 17h44   #8
Evijn
Invité de passage
 
Homme Romain
Étudiant
Inscription : décembre 2012
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Romain
Âge : 22
Localisation : Belgique

Informations professionnelles :
Activité : Étudiant
Secteur : Industrie

Informations forums :
Inscription : décembre 2012
Messages : 8
Points : 2
Points : 2
Ce n'est pas louche comme message d'erreur ?
Citation:
auteur.o(.text+0x141):auteur.cpp: undefined reference to `Personne::Nom'
Je ne comprend pas bien ce qu'il veut dire :/
Evijn est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2012, 17h48   #9
zhouyu
Membre habitué
 
Avatar de zhouyu
 
Homme Loïc
Étudiant
Inscription : octobre 2009
Messages : 83
Détails du profil
Informations personnelles :
Nom : Homme Loïc
Âge : 25
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : octobre 2009
Messages : 83
Points : 129
Points : 129
Tu m'as pris de cour ^^ Fini ta classe Personne tu n'as pas écrit toutes les méthodes dans le .cpp
zhouyu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2012, 18h21   #10
JolyLoic
Rédacteur/Modérateur
 
Avatar de JolyLoic
 
Homme Loïc Joly
Développeur informatique
Inscription : août 2004
Messages : 4 698
Détails du profil
Informations personnelles :
Nom : Homme Loïc Joly
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2004
Messages : 4 698
Points : 9 964
Points : 9 964
Citation:
Envoyé par zhouyu Voir le message
Salut.
Je pense que l'erreur vient de ce code :
Code :
1
2
3
4
5
6
// fonctions membres
char* Auteur::getNom()
{
    for(int i=0 ; i<4 ; i++)
    return Nom[i]; 
}
Tu dois renvoyer un char * et tu renvoies un char, de plus la methode est fausse.
Nom est un tableau de 4 pointeurs. Donc, quand il retourne Nom[i], il retourne bien un pointeur. De plus, ce genre d'erreur serait une erreur de compilation, pas une erreur de link.
Citation:
Envoyé par zhouyu Voir le message
Ce que tu as écrit est : pour chaque i je renvoie le i ème caractère.
Cependant au premier return la fonction s’arrête.
Là, je suis d'accord, la boucle es louche...
Citation:
Envoyé par zhouyu Voir le message
EDIT : en faite tu n'as pas écrit toutes les méthodes de Personne.h dans Personne.cpp ... donc il ne peut pas faire la liaison.
En effet, mais on n'aurait pas une erreur de liaison sur Nom, mais sur ces fonctions manquantes...
Citation:
Envoyé par zhouyu Voir le message
Tu es déjà censé écrire une fonction getNom() dans Personne. Si dans auteur elle fait la même chose pas besoin d'en refaire une .
Là aussi, d'accord, et si on voulait la refaire, il faudrait probablement faire autrement (virtuelle, par exemple).

En fait, le code comporte tout un tas de petits soucis, que je n'ai pas signalés afin de laisser Evijn les découvrir pas lui même une fois qu'il sera débloqué, mais aucun qui pour moi conduirait à l'erreur de link rencontrée.
__________________
Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
JolyLoic est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2012, 18h25   #11
JolyLoic
Rédacteur/Modérateur
 
Avatar de JolyLoic
 
Homme Loïc Joly
Développeur informatique
Inscription : août 2004
Messages : 4 698
Détails du profil
Informations personnelles :
Nom : Homme Loïc Joly
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2004
Messages : 4 698
Points : 9 964
Points : 9 964
Citation:
Envoyé par Evijn Voir le message
Ce n'est pas louche comme message d'erreur ?
Je ne comprend pas bien ce qu'il veut dire :/
En fait, ce qu'il te dis, c'est que dans le fichier auteur.o, issu de auteur.cpp, il a besoin de quelquechose nommé Personne::Nom, mais qu'il n'arrive pas à trouver où cet objet est défini...

Pour tester, si tu crées un nouveau projet, où tu rassemble tout le code dans un seul fichier cpp, as-tu encore un soucis ?

PS : N'hésite pas à utiliser la balise [code] (le bouton #) plutôt que [quote] pour citer code source ou messages d'erreur.
__________________
Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
JolyLoic est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/12/2012, 11h02   #12
Evijn
Invité de passage
 
Homme Romain
Étudiant
Inscription : décembre 2012
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Romain
Âge : 22
Localisation : Belgique

Informations professionnelles :
Activité : Étudiant
Secteur : Industrie

Informations forums :
Inscription : décembre 2012
Messages : 8
Points : 2
Points : 2
Citation:
Envoyé par zhouyu Voir le message
Salut.
Je pense que l'erreur vient de ce code :
Code :
1
2
3
4
5
6
// fonctions membres
char* Auteur::getNom()
{
    for(int i=0 ; i<4 ; i++)
    return Nom[i]; 
}
Tu dois renvoyer un char * et tu renvoies un char, de plus la methode est fausse.
Ce que tu as écrit est : pour chaque i je renvoie le i ème caractère.
Cependant au premier return la fonction s’arrête. Tu renvoies toujours Nom[0].
Dans ton cas tu devrais avoir seulement :
Code :
1
2
3
4
5
 
char* Auteur::getNom()
{
    return Nom; 
}
Je ne vois pas bien. Ce que je pense être en train de faire, c'est créer un tableau de pointeurs de chaîne de caractère. Donc chaque case du tableau pointe vers un mot.
Ainsi quand je fais ma boucle, je demande de retourner le char pointé dans la i ème case du tableau.. Je me trompe ?

De plus quand j'écris :

Citation:
Code :
1
2
3
4
5
 
char* Auteur::getNom()
{
    return Nom; 
}
Il me met un message d'erreur

Citation:
cannot convert `char**' to `char*' in return
Ce que je trouve logique

Citation:
EDIT : en faite tu n'as pas écrit toutes les méthodes de Personne.h dans Personne.cpp ... donc il ne peut pas faire la liaison.
Tu es déjà censé écrire une fonction getNom() dans Personne. Si dans auteur elle fait la même chose pas besoin d'en refaire une .
J'ai écris getNom dans Personne.cpp ça ne change rien malheureusement :-(

Citation:
Pour tester, si tu crées un nouveau projet, où tu rassemble tout le code dans un seul fichier cpp, as-tu encore un soucis ?
Oui, la même chose
Evijn est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/12/2012, 12h22   #13
JolyLoic
Rédacteur/Modérateur
 
Avatar de JolyLoic
 
Homme Loïc Joly
Développeur informatique
Inscription : août 2004
Messages : 4 698
Détails du profil
Informations personnelles :
Nom : Homme Loïc Joly
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2004
Messages : 4 698
Points : 9 964
Points : 9 964
Citation:
Envoyé par Evijn Voir le message
Oui, la même chose
Tu peux passer ce fichier rassemblant tout ?
__________________
Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
JolyLoic est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/12/2012, 13h02   #14
Evijn
Invité de passage
 
Homme Romain
Étudiant
Inscription : décembre 2012
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Romain
Âge : 22
Localisation : Belgique

Informations professionnelles :
Activité : Étudiant
Secteur : Industrie

Informations forums :
Inscription : décembre 2012
Messages : 8
Points : 2
Points : 2
Code :
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <cstdlib>
#include <iostream>
 
using namespace std;
 
class Personne
{
    protected:
        // je décide que l'on doit mettre 4 noms
        static char* Nom[4];
 
	public:
		// class constructor
        Personne();
		Personne(char* name[4]);
		Personne(const Personne &pp);
 
		//fonction membre
		char* getNom();
		void setNom(char* name[4]);
        void displayName(void);
 
        // class destructor
		~Personne();
};
 
Personne::Personne()
{
    for(int i=0 ; i<4 ; i++)
	Nom[i]=0;
}
/*
Personne::Personne(char* name[4])       // constructeur d'initialisation
{
     for(int i=0 ; i<4 ; i++)
     {
         Nom[i]=new char[strlen(name[i])+1]; 
         strcpy(Nom[i], name[i]);
     }
}
*/
Personne::Personne(const Personne &pp)
{
     for(int i=0 ; i<4 ; i++)
     {
         Nom[i] = new char[strlen(pp.Nom[i])+1];
         strcpy(Nom[i], pp.Nom[i]);
     }
}
 
// fonctions membres
char* Personne::getNom()
{
    for(int i=0 ; i<4 ; i++)
        return Nom[i];
}
 
void Personne::setNom(char* name[4])
{
    for(int i=0 ; i<4 ; i++)
    {
        Nom[i]= new char(strlen(name[i])+1);
        strcpy(Nom[i],name[i]);
    }
}
 
// class destructor
Personne::~Personne()
{
     for(int i=0 ; i<4 ; i++)
     if (Nom[i]) 
     {
       delete Nom[i];
     }
}
 
class Auteur : public Personne
{
	public:
		// class constructor
		Auteur();
		Auteur(char* name[4]):Personne(name){}      // car les constructeurs d'initialisation ne sont jamais hérités
 
		//fonction membre
		void displayName(void);
 
		// class destructor
		~Auteur();
};
 
void Auteur::displayName(void)
{
    cout << "Auteurs: " ;
    for(int i=0 ; i<4 ; i++)
        cout << Nom[i] << " ";
    cout << endl;
}
 
int main(int argc, char *argv[])
{   
    Auteur* a;
    Auteur aa;
 
    char* name[4] = {"Oncle Bens" , "Oncle Picsou" , "Oncle Tom" , "Oncle Cloclo"};
    a->setNom(name);
    /* on aurait également pu faire une entrée au clavier */
 
 
    /* Ceci est pour la version 2 : */
    aa.displayName(); 
 
    system("PAUSE");
    return EXIT_SUCCESS;
}
Je n'avais remis dans cet essai que ce qui concerne mon problème évidement, le reste de mon programme fonctionne.
Evijn est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/12/2012, 14h16   #15
r0d
Expert Confirmé Sénior
 
Inscription : août 2004
Messages : 3 700
Détails du profil
Informations personnelles :
Localisation : Belgique

Informations forums :
Inscription : août 2004
Messages : 3 700
Points : 4 525
Points : 4 525
Bonjour,

je t'invite à lire la faq suivante, je pense que tu trouveras la solution à ton problème: http://cpp.developpez.com/faq/cpp/?page=static
r0d est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/12/2012, 15h13   #16
koala01
Modérateur
 
Avatar de koala01
 
Philippe Dunski
Inscription : octobre 2004
Messages : 8 753
Détails du profil
Informations personnelles :
Nom : Philippe Dunski
Âge : 41

Informations forums :
Inscription : octobre 2004
Messages : 8 753
Points : 13 727
Points : 13 727
Envoyer un message via MSN à koala01 Envoyer un message via Skype™ à koala01
Salut,
Citation:
Envoyé par Evijn Voir le message
Je ne vois pas bien. Ce que je pense être en train de faire, c'est créer un tableau de pointeurs de chaîne de caractère. Donc chaque case du tableau pointe vers un mot.
Ainsi quand je fais ma boucle, je demande de retourner le char pointé dans la i ème case du tableau.. Je me trompe ?
Oui, et plutôt lourdement...

Il faut bien comprendre que le fait d'avoir un return te fait quitter la fonction dans laquelle tu te trouves (getNom, en l'occurrence), quel que soit le niveau d'imbrication de portée dans lequel tu te trouve.

C'est à dire que tu entre dans une boucle, mais, comme tu fais un return "inconditionnel" (tu n'as mis strictement aucune condition pour éviter de passer par le return), il sera effectué "à chaque passage dans la boucle"...

Sauf que... une seule exécution de return suffit pour quitter la fonction et que tu passeras systématiquement par le return alors que i est égal à 0

Autrement dit, ta boucle indique "je veux faire quelque chose quatre fois", mais le code qu'il y a dans la boucle fait que, quoi qu'il arrive, tu sortiras de la fonction à la première itération (lorsque i est égal à 0), et donc, tu renverras toujours... la première chaine de caractères, quoi qu'il arrive.

Au final :
  1. Soit la boucle est purement inutile et tu renvoies d'office la première chaine
  2. Soit la boucle est utile, mais, dans ce cas, il manque à tout le moins une condition pour décider (ou non) de renvoyer l'une des chaines et, très vraisemblablement, une information qui te permettra de vérifier la condition
__________________
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
je ne répondrai à aucune question technique par E-mail, message visiteur ou message privé
Vous avez obtenu votre réponse pensez au bouton en bas de page
koala01 est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/12/2012, 15h49   #17
JolyLoic
Rédacteur/Modérateur
 
Avatar de JolyLoic
 
Homme Loïc Joly
Développeur informatique
Inscription : août 2004
Messages : 4 698
Détails du profil
Informations personnelles :
Nom : Homme Loïc Joly
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2004
Messages : 4 698
Points : 9 964
Points : 9 964
En effet, le code que tu mets est différent du premier que tu avais posté. Et ce static devant Nom change tout. Fait bien attention à poster exactement le code que tu as, sinon, difficile de t'aider.

Si tu l'enlèves, tu n'as plus cette erreur de link (mais d'autres soucis, que je te laisse le soin de creuser un peu tout seul, avant de revenir vers nous si tu as des soucis).
__________________
Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
JolyLoic est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/12/2012, 16h52   #18
Evijn
Invité de passage
 
Homme Romain
Étudiant
Inscription : décembre 2012
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Romain
Âge : 22
Localisation : Belgique

Informations professionnelles :
Activité : Étudiant
Secteur : Industrie

Informations forums :
Inscription : décembre 2012
Messages : 8
Points : 2
Points : 2
Citation:
Envoyé par koala01 Voir le message
Il faut bien comprendre que le fait d'avoir un return te fait quitter la fonction dans laquelle tu te trouves (getNom, en l'occurrence), quel que soit le niveau d'imbrication de portée dans lequel tu te trouve.
D'accord merci beaucoup je n'avais pas pensé à ça

Citation:
Envoyé par JolyLoic Voir le message
En effet, le code que tu mets est différent du premier que tu avais posté. Et ce static devant Nom change tout. Fait bien attention à poster exactement le code que tu as, sinon, difficile de t'aider.

Si tu l'enlèves, tu n'as plus cette erreur de link.
Désolé j'avais mis ce static en chipotant en cherchant une solution par moi-même et j'avais oublié de le retirer.

Citation:
Envoyé par r0d Voir le message
Bonjour,

je t'invite à lire la faq suivante, je pense que tu trouveras la solution à ton problème: http://cpp.developpez.com/faq/cpp/?page=static
J'ai lu la FAQ (qui est très bien faite par ailleurs, merci aux auteurs ) et je pense qu'une variable membre statique n'est pas ce qu'il faut pour mon programme.

Voici toujours la derniere version que j'ai, avec le getNom que j'ai modifié en conséquence:

Code :
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <cstdlib>
#include <iostream>
 
using namespace std;
 
class Personne
{
    protected:
        // je décide que l'on doit mettre 4 noms
        char* Nom[4];
 
    public:
		// class constructor
        Personne();
		Personne(char* name[4]);
		Personne(const Personne &pp);
 
		//fonction membre
		char* getNom(int i);
		void setNom(char* name[4]);
        void displayName(void);
 
        // class destructor
		~Personne();
};
 
Personne::Personne()
{
    for(int i=0 ; i<4 ; i++)
        Nom[i]=0;
}
Personne::Personne(char* name[4])            // constructeur d'initialisation
{
     for(int i=0 ; i<4 ; i++)
     {
         Nom[i]=new char[strlen(name[i])+1]; 
         strcpy(Nom[i], name[i]);
     }
}
Personne::Personne(const Personne &pp)       // constructeur de copie
{
     for(int i=0 ; i<4 ; i++)
     {
         Nom[i] = new char[strlen(pp.Nom[i])+1];
         strcpy(Nom[i], pp.Nom[i]);
     }
}
 
// fonctions membres
char* Personne::getNom(int i)
{
        return Nom[i];
}
 
void Personne::setNom(char* name[4])
{
    for(int i=0 ; i<4 ; i++)
    {
        Nom[i]= new char(strlen(name[i])+1);
        strcpy(Nom[i],name[i]);
    }
}
 
// class destructor
Personne::~Personne()
{
     for(int i=0 ; i<4 ; i++)
     if (Nom[i]) 
     {
       delete Nom[i];
     }
}
 
class Auteur : public Personne
{
	public:
		// class constructor
		Auteur();
		Auteur(char* name[4]):Personne(name){}      // car les constructeurs d'initialisation ne sont jamais hérités
 
		//fonction membre
		void displayName(void);
 
		// class destructor
		~Auteur();
};
 
void Auteur::displayName(void)
{
    cout << "Auteurs: " ;
    for(int i=0 ; i<4 ; i++)
        cout << getNom(i) << " ";
    cout << endl;
}
 
int main(int argc, char *argv[])
{   
    Auteur* a;
    Auteur aa;
 
    char* name[4] = {"Oncle Bens" , "Oncle Picsou" , "Oncle Tom" , "Oncle Cloclo"};
    a->setNom(name);
 
    aa.displayName(); 
 
    system("PAUSE");
    return EXIT_SUCCESS;
}

J'ai toujours une erreur de linker mais différente cette fois ci ! On dirait que j'avance

Voici les logs de la compilation:

Citation:
Compiler: Default compiler
Building Makefile: "C:\Dev-Cpp\test\Makefile.win"
Executing make...
make.exe -f "C:\Dev-Cpp\test\Makefile.win" all
g++.exe -c main.cpp -o main.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"C:/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"C:/Dev-Cpp/include/c++/3.4.2" -I"C:/Dev-Cpp/include"

g++.exe main.o -o "Test.exe" -L"C:/Dev-Cpp/lib"

main.o(.text+0x4e6):main.cpp: undefined reference to `Auteur::Auteur()'
main.o(.text+0x544):main.cpp: undefined reference to `Auteur::~Auteur()'
main.o(.text+0x577):main.cpp: undefined reference to `Auteur::~Auteur()'
collect2: ld returned 1 exit status

make.exe: *** [Test.exe] Error 1

Execution terminated
Evijn est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/12/2012, 18h26   #19
zhouyu
Membre habitué
 
Avatar de zhouyu
 
Homme Loïc
Étudiant
Inscription : octobre 2009
Messages : 83
Détails du profil
Informations personnelles :
Nom : Homme Loïc
Âge : 25
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : octobre 2009
Messages : 83
Points : 129
Points : 129
Salut.
Désolé pour mon erreur je n'avais pas vu que c'etait un tableau de char* ...
Pour ton erreur de linker toujours la même chose tu déclares des méthodes dans Author que tu n'implémentes pas :/
zhouyu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/01/2013, 19h50   #20
Evijn
Invité de passage
 
Homme Romain
Étudiant
Inscription : décembre 2012
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Romain
Âge : 22
Localisation : Belgique

Informations professionnelles :
Activité : Étudiant
Secteur : Industrie

Informations forums :
Inscription : décembre 2012
Messages : 8
Points : 2
Points : 2
Bonsoir

J'ai résolu mon problème.
En fait j'avais deux grosses erreurs, à savoir:

- Je n'avais pas implémenté le constructeur par défaut dans ma classe 'Auteur' (celui ci n'est pas hérité si on redéfini le constructeur d'initialisation d'après ce que j'ai compris), et je n'avais pas besoin de redéfinir un destructeur.

- Je n'avais pas correctement initialisé mes auteurs dans mon main (j'ai choisi de passer directement via le constructeur d'initialisation car je me cassais les dents sur ma fonction 'setNom' ).

Voici mon code final, fonctionnel, au cas où quelqu'un rencontrerait un problème similaire.

Code :
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
 
#include <cstdlib>
#include <iostream>
#include <string.h>
 
using namespace std;
 
class Personne
{
    protected:
        // je décide que l'on doit mettre 4 noms
        char* Nom[4];
 
	public:
		// class constructor
        Personne();
		Personne(char* name[4]);
		Personne(Personne &pp);
 
		//fonction membre
		char* getNom(int i);
                void displayName(void);
 
        // class destructor
		~Personne();
};
 
Personne::Personne()
{
    for(int i=0 ; i<4 ; i++)
        Nom[i]=0;
}
Personne::Personne(char* name[4])            // constructeur d'initialisation
{
     for(int i=0 ; i<4 ; i++)
     {
         Nom[i]=new char[strlen(name[i])+1]; 
         strcpy(Nom[i], name[i]);
     }
}
Personne::Personne(Personne &pp)       // constructeur de copie
{
     for(int i=0 ; i<4 ; i++)
     {
         Nom[i] = new char[strlen(pp.Nom[i])+1];
         strcpy(Nom[i], pp.Nom[i]);
     }
}
 
// fonctions membres
char* Personne::getNom(int i)
{
      if(i > 3 || i < 0)
           return 0;
      else
          return Nom[i];
}
 
// class destructor
Personne::~Personne()
{
     for(int i=0 ; i<4 ; i++)
     if (Nom[i]) 
     {
       delete Nom[i];
     }
}
 
class Auteur : public Personne
{
	public:
		// class constructor
		Auteur();                                   // si on redef le construct d'init, celui ci doit l'être aussi
		Auteur(char* name[4]):Personne(name){}      // car les constructeurs d'initialisation ne sont jamais hérités
 
		//fonction membre
		void displayName(void);
 
		// class destructor => no need
		//~Auteur();
};
 
Auteur::Auteur():Personne(){}                          // il reprend ainsi Personne::Personne();
 
void Auteur::displayName(void)
{
    cout << "Auteurs: " ;
    for(int i=0 ; i<4 ; i++)
        cout << getNom(i) << " ";
    cout << endl;
}
 
int main(int argc, char *argv[])
{   
    Auteur* a;
 
    char* name[4] = { "riri", "fifi", "loulou", "donald" };
    a = new Auteur(name);
 
    a->displayName(); 
 
    system("PAUSE");
    return EXIT_SUCCESS;
}

Merci à tous pour votre aide
Je marque le sujet comme résolu
Evijn est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 20h05.


 
 
 
 
Partenaires

Hébergement Web