Problème template c++

Problème template c++ - C++ - Programmation

Marsh Posté le 05-11-2011 à 21:28:20    

Bonjour à tous et à toutes,
 
Je rencontre un problème que je ne parviens pas à résoudre avec les templates.
 
En fait, j'ai une classe template Vecteur (qui agit comme un vecteur...). Elle agit normalement lorsque le type est un entier, par contre, dés qu'il s'agit d'une classe, on dirait que la fonction membre d'affichage des éléments oublie le type (alors que si je l'affiche élément par élément tout se passe bien).
 
J'utilise g++ v3.4.3 sur Solaris 10.
 
Voici le code de la classe Vecteur (header et cxx)  

Code :
  1. #ifndef VECTEUR_H
  2. #define VECTEUR_H
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <iostream.h>
  6. #include <string.h>
  7. #include "Structure.h"
  8. #include "ExceptionBase.h"
  9. template <class type>
  10. class Vecteur : public Structure<type>
  11. {
  12. private:
  13.  type* tab;
  14.  int* VecPresence;
  15. public:
  16.  Vecteur();
  17.  Vecteur(int TmpNbrElements);
  18.  type& getElement(int TmpIndice);
  19.  void setElement(int TmpIndice,const type& TmpObj);
  20.  type retireElement(int TmpIndice);
  21.  bool estOccupe(int TmpIndice);
  22.  bool indiceValide(int TmpIndice);
  23.  void affiche();
  24.  Vecteur<type> operator+(const type& TmpObj);
  25.  int PremierLibre();
  26.  ~Vecteur();
  27. };
  28. #endif


 

Code :
  1. #include "Vecteur.h"
  2. template <class type>
  3. Vecteur<type>::Vecteur()
  4. {
  5. Structure<type>::setNbrElements(0);
  6. }
  7. template <class type>
  8. Vecteur<type>::Vecteur(int TmpNbrElements)
  9. {
  10. int i=0;
  11. Structure<type>::setNbrElements(TmpNbrElements);
  12. tab = new type[Structure<type>::NbrElements];
  13. VecPresence = new int[Structure<type>::NbrElements];
  14. while(i < Structure<type>::NbrElements)
  15. {
  16.  *(VecPresence +i) = 0;
  17.  i++;
  18. }
  19. }
  20. template <class type>
  21. type& Vecteur<type>::getElement(int TmpIndice)
  22. {
  23. if(indiceValide(TmpIndice) && estOccupe(TmpIndice)) {
  24.            
  25.             return *(tab+TmpIndice);
  26.            }
  27. else throw ExceptionBase("Case non occupee ou indice invalide" );
  28. }
  29. template <class type>
  30. void Vecteur<type>::setElement(int TmpIndice,const type& TmpObj)
  31. {
  32. if(indiceValide(TmpIndice))
  33. {
  34.     *(tab + TmpIndice) = TmpObj;
  35.  *(VecPresence + TmpIndice) = 1;
  36. }
  37. else throw ExceptionBase("Indice invalide" );
  38. }
  39. template <class type>
  40. type Vecteur<type>::retireElement(int TmpIndice)
  41. {
  42. if(indiceValide(TmpIndice) && estOccupe(TmpIndice))
  43. {
  44.  type TmpObj;
  45.  TmpObj = *(tab + (TmpIndice));
  46.  *(VecPresence + (TmpIndice))=0;
  47.  return TmpObj;
  48. }
  49. else throw ExceptionBase("Indice invalide ou case inoccupee" );
  50. }
  51. template <class type>
  52. bool Vecteur<type>::estOccupe(int TmpIndice)
  53. {
  54. bool ok = indiceValide(TmpIndice);
  55. if(ok)
  56. {
  57.  if(*(VecPresence + (TmpIndice)) == 1) return true;
  58.  else return false;
  59. }
  60. else throw ExceptionBase("Indice invalide" );
  61. }
  62. template <class type>
  63. bool Vecteur<type>::indiceValide(int TmpIndice)
  64. {
  65. if((TmpIndice <= Structure<type>::NbrElements-1) && TmpIndice >= 0) return true;
  66. else return false;
  67. }
  68. template <class type>
  69. void Vecteur<type>::affiche()  //le problème viendrait apparement de cette méthode
  70. {
  71. int Indice=0;
  72. while(Indice<(Structure<type>::NbrElements))
  73. {     
  74.  cout<<Indice<<". "<<endl;
  75.  cout<<tab[Indice]<<endl;    //Toutes les classes utilisées implémentent une surcharge de << qui fonctionne
  76.  cout<<"------------------------------------------"<<endl;
  77.  Indice++;
  78. }
  79. }
  80. template <class type>
  81. Vecteur<type> Vecteur<type>::operator+(const type& TmpObj)
  82. {
  83. int TmpIndice= 0;
  84. TmpIndice = PremierLibre();
  85. setElement(TmpIndice, TmpObj);
  86. return *this;
  87. }
  88. template <class type>
  89. int Vecteur<type>::PremierLibre()
  90. {
  91. int TmpIndice = 0;
  92. while((TmpIndice < Structure<type>::NbrElements) && (*(VecPresence + TmpIndice) != 0))
  93. {
  94.  TmpIndice++;
  95. }
  96. if (TmpIndice >= Structure<type>::NbrElements) throw ExceptionBase("Vecteur plein" );
  97. else return TmpIndice;
  98. }
  99. template <class type>
  100. Vecteur<type>::~Vecteur()
  101. {
  102. if(tab)
  103. {
  104.  delete []tab;
  105.  delete []VecPresence;
  106. }
  107. }
  108. template class Vecteur<int>;
  109. #include "Carte.h"
  110. template class Vecteur<Carte>;
  111. #include "Collectionneur.h"
  112. template class Vecteur<Collectionneur>;
  113. #include "ConcepteurAlbum.h"
  114. template class Vecteur<ConcepteurAlbum>;


 
La classe template Structure n'est qu'une classe générique, je ne pense pas qu'il soit possible que le problème vienne de là.
Voici le résultat (l'endroit ou ça casse).
 
Personne
Nom : Coptere                                         //test d'une des classe, ici, c'est déjà un problème puisqu'apparement il affiche
Prenom : Eli                                          //le type comme si il s'agissait d'une des classes mère de ma classe concernee
Date de naissance : 25/03/1990
Nationalite : francais
------------------------------------------
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX   //Cette ligne est dans le main()
Collect                                              //affichage qui sert à tracer la surcharge du << dans chaque classe de la  
Personne                                             //Hièrarchie
Nom : Sonite
Prenom : Sam
Date de naissance : 11/01/1992
Nationalite : belge
Author
Login : sonitesa
Nombre de Collections : 6
On ajoute Sonite en utilisant l'operateur +
Author
0.
Personne
Nom :                                //S'arrête ici
 
 
Voilà, ici (mais c'est pareil avec les autres classes) il s'agit d'une hièrarchie ;
 
class Personne (Classe mère)
class AuthorisedPerson : public Personne (Classe abstraite)
class Collectionneur : public AuthorisedPerson
class ConcepteurAlbum : public AuthorisedPerson
 
Je suis désolé de ne pas pouvoir rendre le problème plus général avec un code plus court. Je pense qu'il doit s'agir d'un cas assez particulier.
 
Voilà, en espèrant que vous pourrez m'aider. Si besoin, je peux ajouter les valeurs que peuvent prendre le type (le code des différentes classes).
J'ajoute qu'il s'agit d'un cas d'école et que je suis obligé de travailler comme ça.
 
Je vous remercie d'avance.
 
Bonne soirée.
 
Christallis

Reply

Marsh Posté le 05-11-2011 à 21:28:20   

Reply

Marsh Posté le 05-11-2011 à 23:52:57    

donne ton main.
 
Un template doit être défini aussi dans le .h et non pas dans un .cpp
 
Edit : à la lecture de ton code, j'ai comme l'impression que tu espères que l'opérateur << pourra bénéficier du polymorphisme. Ce n'est pas le cas. Donne aussi quelques exemples de classes que tu utilises, comme Carte, Collectionneur, ConcepteurAlbum et les classes dérivées s'il y en a,et montre nous, dans ton main donc, les appels que tu fais.


Message édité par theshockwave le 05-11-2011 à 23:55:40

---------------
last.fm
Reply

Marsh Posté le 06-11-2011 à 10:56:48    

Bonjour,
 
Tout d'abord, merci pour ta réponse.
 
Oui, en effet normalement le code d'un template doit être dans le header mais j'ai essayé de tout mettre dans le header (et aussi (même si c'est pareil) d'inclure le cxx à la fin du header) et ça ne change absolument rien à l'exécution.
 
Voici le main (enfin, la partie concernée qui est faite dans un fonction void).
 

Code :
  1. void main()
  2. {
  3.   cout << "-----  Test du template Vecteur avec des objets de la classe Collectionneur ------" << endl;
  4.   cout << "Creation  d'un vecteur de 5 cases..." << endl;
  5.   Vecteur<Collectionneur> *p = new Vecteur<Collectionneur>(5);
  6.   p->affiche();               
  7.   cout << endl;
  8.  
  9.   Collectionneur c1("Tombale","Pierre","07/10/1985","belge","tombalpi",3);
  10.   Collectionneur c2("Coptere","Eli","25/03/1990","francais","copterel",4);
  11.   cout << "L'element d'indice 2 devient Tombale" << endl;
  12.   if (p->indiceValide(2)) p->setElement(2,c1);
  13.   p->affiche();                                 
  14.   cout << endl;
  15.  
  16.   cout << "L'element d'indice 4 devient Coptere" << endl;
  17.   if (p->indiceValide(4)) p->setElement(4,c2);
  18.   p->affiche();                                 
  19.   cout << endl;
  20.   cout << "On recupere l'element d'indice 2 (sans le retirer !!!)" << endl;
  21.   if (p->indiceValide(2) && p->estOccupe(2))
  22.   {
  23.     Collectionneur c=p->getElement(2);   
  24.    
  25.     cout << "Element recupere = " << c << endl;
  26.   }
  27.   else cout << "Case non occupee ou indice invalide !" << endl;
  28.   cout << endl;
  29.   cout << "On recupere l'element d'indice 3 (sans le retirer !!!)" << endl;
  30.   if (p->indiceValide(3) && p->estOccupe(3))   // exception
  31.   {
  32.     Collectionneur c = p->getElement(3);
  33.     cout << "Element recupere = " << c << endl;
  34.   }
  35.   else cout << "Case non occupee ou indice invalide !" << endl;
  36.   cout << endl;
  37.   p->affiche();
  38.   cout << endl;
  39.   cout << "On retire l'element d'indice 2" << endl;
  40.   if (p->indiceValide(2) && p->estOccupe(2))   // exception
  41.   {
  42.     Collectionneur c = p->retireElement(2);
  43.     cout << "Element recupere = " << c << endl;
  44.   }
  45.   else cout << "Case non occupee ou indice invalide !" << endl;
  46.   cout << endl;
  47.   p->affiche(); 
  48.   cout << endl;
  49.   cout << "On ajoute Issier en utilisant l'operateur +" << endl;
  50.   // operator+ : Ajout dans la premiere case libre du vecteur
  51.   (*p) + Collectionneur("Issier","Pol","21/06/1996","belge","issierpo",1);
  52.   p->affiche();   
  53.                                  
  54.   cout << "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" << endl;
  55.   Collectionneur c("Sonite","Sam","11/01/1992","belge","sonitesa",6);
  56. c.affiche();
  57.   cout << "On ajoute Sonite en utilisant l'operateur +" << endl;
  58.   (*p) + c;
  59.   p->affiche();                                       
  60.   cout << endl;
  61.   delete p;
  62. }


 
En fait, il s'agit d'une hiérarchie de classe et chaque classe fille redéfinis brièvement l'opérateur << (en appelant celui de la classe mère).
Voici la hiérarchie dont fait partie la classe Collectionneur ;
 
Header de la classe Personne ;  
 

Code :
  1. #ifndef PERSONNE_H
  2. #define PERSONNE_H
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <iostream.h>
  6. class Personne
  7. {
  8. protected:
  9.  char * Nom;
  10.  char * Prenom;
  11.  char * DateNaissance;
  12.  char * Nationalite;
  13.  char * id;
  14. public:
  15. //Constructeurs
  16.  Personne();
  17.  Personne(const char *TmpNom,const char *TmpPrenom,const char *TmpDateNaissance, const char *TmpNationalite);
  18.  Personne(const Personne& Pers);
  19. //Surcharge d'operateurs
  20.  friend istream& operator>>(istream& s, Personne& Pers);
  21.  friend ostream& operator<<(ostream& s, const Personne& Pers);
  22.  virtual void affiche();
  23.  virtual char* getIdentification();
  24. //Setters
  25.  void setNom(const char* TmpNom);
  26.  void setPrenom(const char* TmpPrenom);
  27.  void setDateNaissance(const char* TmpDateNaissance);
  28.  void setNationalite(const char* TmpNationalite);
  29. //Getters
  30.  char* getNom() const;
  31.  char* getPrenom() const;
  32.  char* getDateNaissance() const;
  33.  char* getNationalite() const;
  34. //Destructeur
  35.  virtual ~Personne();
  36. };
  37. #endif

 
 
Corps ;
 

Code :
  1. #include "Personne.h"
  2. //Constructeurs
  3. Personne::Personne()
  4. {
  5. Nom=NULL;
  6. Prenom=NULL;
  7. DateNaissance=NULL; //Il faudra sans doute remplacer ce champ par une classe Cdate.
  8. Nationalite=NULL;
  9. id=NULL;
  10. setNom("--" );
  11. setPrenom("--" );
  12. setDateNaissance("--/--/--" );
  13. setNationalite("--" );
  14. }
  15. Personne::Personne(const char* TmpNom,const char* TmpPrenom,const char* TmpDateNaissance,const char* TmpNationalite)
  16. {
  17. Nom=NULL;
  18. Prenom=NULL;
  19. DateNaissance=NULL;
  20. Nationalite=NULL;
  21. id=NULL;
  22. setNom(TmpNom);
  23. setPrenom(TmpPrenom);
  24. setDateNaissance(TmpDateNaissance);
  25. setNationalite(TmpNationalite);
  26. }
  27. Personne::Personne(const Personne& Pers)
  28. { Nom=NULL;
  29. Prenom=NULL;
  30. DateNaissance=NULL;
  31. Nationalite=NULL;
  32. id=NULL;
  33. setNom(Pers.getNom());
  34. setPrenom(Pers.getPrenom());
  35. setDateNaissance(Pers.getDateNaissance());
  36. setNationalite(Pers.getNationalite());
  37. }
  38. //Surcharge d'operateurs
  39. istream& operator>>(istream& s, Personne& Pers)
  40. {
  41. char Buffer[100];
  42. Pers.id=NULL;
  43. cout<<"Nom : ";
  44. s>>Buffer;
  45. Pers.setNom(Buffer);
  46. cout<<"Prenom : ";
  47. s>>Buffer;
  48. Pers.setPrenom(Buffer);
  49. cout<<"Date de naissance : ";
  50. s>>Buffer;
  51. Pers.setDateNaissance(Buffer);
  52. cout<<"Nationalite : ";
  53. s>>Buffer;
  54. Pers.setNationalite(Buffer);
  55. return s;
  56. }
  57. ostream& operator<<(ostream& s, const Personne& Pers)
  58. {
  59. cout << "OUT Personne" << endl;
  60. s<<"Nom : "<<Pers.getNom()<<endl;
  61. s<<"Prenom : "<<Pers.getPrenom()<<endl;
  62. s<<"Date de naissance : "<<Pers.getDateNaissance()<<endl;
  63. s<<"Nationalite : "<<Pers.getNationalite()<<endl;
  64. return s;
  65. }
  66. void Personne::affiche()
  67. {cout<<"Personne"<<endl;
  68. cout<<"Nom : "<<getNom()<<endl;
  69. cout<<"Prenom : "<<getPrenom()<<endl;
  70. cout<<"Date de naissance : "<<getDateNaissance()<<endl;
  71. cout<<"Nationalite : "<<getNationalite()<<endl;
  72. }
  73. char* Personne::getIdentification()
  74. {
  75. if(Nom)
  76. {
  77.  int Nblettre = strlen(getNom());
  78.  id = new char[Nblettre+1];
  79.  strcpy(id, getNom());
  80.  return id;
  81. }
  82. else
  83. {
  84.  id = new char[3];
  85.  strcpy(id,"--" );
  86.  return id;
  87. }
  88. }
  89. //Setters
  90. void Personne::setNom(const char* TmpNom)
  91. {
  92. if(TmpNom)
  93. {
  94.  int Nblettre;
  95.  Nblettre = strlen(TmpNom);
  96.  if(Nom) delete Nom;
  97.  Nom = new char[Nblettre+1];
  98.  strcpy(Nom, TmpNom);
  99. }
  100. else
  101.  return;
  102. }
  103. void Personne::setPrenom(const char* TmpPrenom)
  104. {
  105. if(TmpPrenom)
  106. {
  107.  int Nblettre;
  108.  Nblettre = strlen(TmpPrenom);
  109.  if(Prenom) delete Prenom;
  110.  Prenom = new char[Nblettre+1];
  111.  strcpy(Prenom, TmpPrenom);
  112. }
  113. else
  114.  return;
  115. }
  116. void Personne::setDateNaissance(const char* TmpDateNaissance)
  117. {
  118. if(TmpDateNaissance)
  119. {
  120.  int Nblettre;
  121.  Nblettre = strlen(TmpDateNaissance);
  122.  if(DateNaissance) delete DateNaissance;
  123.  DateNaissance = new char[Nblettre+1];
  124.  strcpy(DateNaissance, TmpDateNaissance);
  125. }
  126. else
  127.  return;
  128. }
  129. void Personne::setNationalite(const char* TmpNationalite)
  130. {
  131. if(TmpNationalite)
  132. {
  133.  int Nblettre;
  134.  Nblettre = strlen(TmpNationalite);
  135.  if(Nationalite) delete Nationalite;
  136.  Nationalite = new char[Nblettre+1];
  137.  strcpy(Nationalite, TmpNationalite);
  138. }
  139. else
  140.  return;
  141. }
  142. //Getters
  143. char* Personne::getNom() const
  144. {
  145. return Nom;
  146. }
  147. char* Personne::getPrenom() const
  148. {
  149. return Prenom;
  150. }
  151. char* Personne::getDateNaissance() const
  152. {
  153. return DateNaissance;
  154. }
  155. char* Personne::getNationalite() const
  156. {
  157. return Nationalite;
  158. }
  159. //Destructeur
  160. Personne::~Personne()
  161. {
  162. if(Nom) delete Nom;
  163. if(Prenom) delete Prenom;
  164. if(DateNaissance) delete DateNaissance;
  165. if(Nationalite) delete Nationalite;
  166. if(id) delete id;
  167. }


 
Beaucoup de lignes superflues ont été ajoutée uniquement dans le but de tester/tracer. J'ai fais énormément de test avant de demander de l'aide.
 
Header de la classe AuthorisedPerson (Classe abstraite dérivée de Personne).
 

Code :
  1. #ifndef AUTHORIZEDPERSON_H
  2. #define AUTHORIZEDPERSON_H
  3. #include <iostream.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include "Personne.h"
  7. class AuthorisedPerson : public Personne
  8. {
  9. protected:
  10.  char * Login;
  11. public:
  12.  AuthorisedPerson();
  13.  AuthorisedPerson(const char* TmpNom, const char* TmpPrenom, const char* TmpDateNaissance, const char* TmpNationalite, const char* TmpLogin);
  14.  AuthorisedPerson(const AuthorisedPerson& AuthPers);
  15.  friend istream& operator>>(istream& s, AuthorisedPerson& AuthPers);
  16.  friend ostream& operator<<(ostream& s, const AuthorisedPerson& AuthPers);
  17.  virtual char* getIdentification() = 0;
  18.  void setLogin(const char* TmpLogin);
  19.  char* getLogin() const;
  20.  virtual ~AuthorisedPerson();
  21. };
  22. #endif


 
Cxx ;  
 

Code :
  1. #include "AuthorisedPerson.h"
  2. AuthorisedPerson::AuthorisedPerson() : Personne()
  3. {
  4. //Appel du constructeur par défaut de la classe Personne
  5. Login = NULL;
  6. setLogin("--" );
  7. }
  8. AuthorisedPerson::AuthorisedPerson(const char* TmpNom, const char* TmpPrenom, const char* TmpDateNaissance, const char* TmpNationalite, const char* TmpLogin) : Personne(TmpNom, TmpPrenom, TmpDateNaissance, TmpNationalite)
  9. {
  10. //Appel du constructeur d'initialisation de la classe Personne
  11. Login = NULL;
  12. setLogin(TmpLogin);
  13. }
  14. AuthorisedPerson::AuthorisedPerson(const AuthorisedPerson& AuthPers) : Personne((AuthorisedPerson& )AuthPers)
  15. {
  16. Login = NULL;
  17. setLogin(AuthPers.getLogin());
  18. }
  19. istream& operator>>(istream& s, AuthorisedPerson& AuthPers)
  20. {
  21. char TmpLogin[100];
  22. s>>(Personne& )AuthPers;
  23. cout<<"Login : ";
  24. s>>TmpLogin;
  25. AuthPers.setLogin(TmpLogin);
  26. return s;
  27. }
  28. ostream& operator<<(ostream& s, const AuthorisedPerson& AuthPers)
  29. {
  30. cout << "OUT author" << endl;
  31. s<<(Personne& )AuthPers;
  32. s<<"Login : "<<AuthPers.getLogin()<<endl;
  33. return s;
  34. }
  35. void AuthorisedPerson::setLogin(const char* TmpLogin)
  36. {
  37. if(TmpLogin)
  38.  int Nblettre;
  39.  Nblettre = strlen(TmpLogin);
  40.  if(Login) delete Login;
  41.  Login = new char[Nblettre+1];
  42.  strcpy(Login, TmpLogin);
  43. }
  44. else
  45.  return;
  46. }
  47. char* AuthorisedPerson::getLogin() const
  48. {cout<<"Author"<<endl;
  49. return Login;
  50. }
  51. AuthorisedPerson::~AuthorisedPerson()
  52. {
  53. if(Login) delete Login;
  54. }


 
Header de la classe Collectionneur (suivit du corps) qui dérive de AuthorisedPerson
 

Code :
  1. #ifndef COLLECTIONNEUR_H
  2. #define COLLECTIONNEUR_H
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <iostream.h>
  6. #include "AuthorisedPerson.h"
  7. class Collectionneur : public AuthorisedPerson
  8. {
  9. private:
  10.  int NbCollections;
  11. public:
  12. //Constructeurs
  13.  Collectionneur();
  14.  Collectionneur(const char* TmpNom, const char* TmpPrenom, const char* TmpDateNaissance, const char* TmpNationalite, const char* TmpLogin, const int TmpNbCollections);
  15.  Collectionneur(const Collectionneur& TmpCol);
  16. //Surcharges d'operateurs
  17. Collectionneur& operator=(const Collectionneur& TmpCol);
  18.  friend istream& operator>>(istream& s, Collectionneur& Col);
  19.  friend ostream& operator<<(ostream& s, const Collectionneur& Col);
  20. //Setter(s)
  21.  void setNbCollections(const int TmpNbCollections);
  22. //Getter(s)
  23.  int getNbCollections() const;
  24.  void affiche();
  25.  char* getIdentification();
  26.  //~Collectionneur();
  27. };
  28. #endif


 
Collectionneur.cxx
 

Code :
  1. #include "Collectionneur.h"
  2. Collectionneur::Collectionneur() : AuthorisedPerson()
  3. {
  4. setNbCollections(0);
  5. }
  6. Collectionneur::Collectionneur(const char* TmpNom, const char* TmpPrenom, const char* TmpDateNaissance, const char* TmpNationalite, const char* TmpLogin, const int TmpNbCollections) : AuthorisedPerson(TmpNom, TmpPrenom, TmpDateNaissance, TmpNationalite, TmpLogin)
  7. {
  8. setNbCollections(TmpNbCollections);
  9. }
  10. Collectionneur::Collectionneur(const Collectionneur& TmpCol) : AuthorisedPerson((AuthorisedPerson& )TmpCol)
  11. {
  12. setNbCollections(TmpCol.getNbCollections());
  13. }
  14. Collectionneur& Collectionneur::operator=(const Collectionneur& TmpCol)
  15. {
  16. /*Nom=NULL;
  17. Prenom=NULL;
  18. DateNaissance=NULL;
  19. Nationalite=NULL;
  20. id=NULL;
  21. Login=NULL;*/
  22. setNom(TmpCol.getNom());
  23. setPrenom(TmpCol.getPrenom());
  24. setDateNaissance(TmpCol.getDateNaissance());
  25. setNationalite(TmpCol.getNationalite());
  26. setLogin(TmpCol.getLogin());
  27. setNbCollections(TmpCol.getNbCollections());
  28. return *this;
  29. }
  30. istream& operator>>(istream& s, Collectionneur& Col)
  31. {
  32. cout << "IN" << endl;
  33. int TmpCol=0;
  34. s>>(AuthorisedPerson& )Col;
  35. cout<<"Nombre de Collections : ";
  36. s>>TmpCol;
  37. Col.setNbCollections(TmpCol);
  38. return s;
  39. }
  40. ostream& operator<<(ostream& s, const Collectionneur& Col)
  41. {
  42. cout << "OUT collect" << endl;
  43. s<<(AuthorisedPerson& )Col;
  44. s<<"Nom : " << Col.getNom() << endl;
  45. s<<"Login : " << Col.getLogin() << endl;
  46. s<<"Nombre de collections : "<<Col.getNbCollections()<<endl;
  47. return s;
  48. }
  49. void Collectionneur::setNbCollections(const int TmpNbCollections)
  50. {
  51. if(TmpNbCollections >= 0) NbCollections = TmpNbCollections;
  52. else return;
  53. }
  54. int Collectionneur::getNbCollections() const
  55. {
  56. return NbCollections;
  57. }
  58. void Collectionneur::affiche()
  59. {cout<<"Collect"<<endl;
  60. Personne::affiche();
  61. cout<<"Login : "<<getLogin()<<endl;
  62. cout<<"Nombre de Collections : "<<getNbCollections()<<endl;
  63. }
  64. char* Collectionneur::getIdentification()
  65. {
  66. if(Nom)
  67. {
  68.  int Nblettre = strlen(getNom());
  69.  id = new char[Nblettre+10];
  70.  sprintf(id, "COLLECTIONNEUR:%s#%d", getNom(),getNbCollections());
  71.  return id;
  72. }
  73. else
  74. {
  75.  id = new char[22];
  76.  strcpy(id,"COLLECTIONNEUR:--#00" );
  77.  return id;
  78. }
  79. }


 
Voilà, je rappel qu'il s'agit d'un cas d'école.
 
Merci de ton aide.


Message édité par christallis le 06-11-2011 à 11:01:16
Reply

Marsh Posté le 06-11-2011 à 15:58:40    

y'aurait plein de choses à redire. Il manque la déclaration de ton template Structure pour être exhaustif.
Cela dit, je pense que le premier problème auquel tu te butes, c'est qu'il manque la déclaration de tes opérateurs.
 
Ton prof attend sans doute que tu mettes en avant le polymorphisme. Du coup, tu n'as besoin que d'un seul opérateur qui prend en entrée une Personne (par référence constante comme tu le fais très bien). Déclare une fonction d'affichage qui va être virtuelle au niveau de personne, et surcharge-là à chaque étage de ton héritage. Retire tes autres opérateurs, et surtout, déclare les opérateurs dans tes .h (l'implémentation reste dans le .cpp)
 
Ensuite, attention à tes sprintf, ils sont complètement faux. Par exemple :

Code :
  1. int Nblettre = strlen(getNom());
  2.   id = new char[Nblettre+10];
  3.   sprintf(id, "COLLECTIONNEUR:%s#%d", getNom(),getNbCollections());


là, tu demandes un buffer pour écrire une chaine. Tu sais que cette chaine va être de la taille de ce que tu mets en dur dans ton formatage (au moins 16 caractères) + la taille du nom (c'est bien, tu en as tenu compte) + la taille en caractères du nombre de collections (log à base 10 de ce nombre) + 1 pour le zéro terminal. Avec le code que tu as écrit, c'est sur que tu débordes. Ca peut faire tout et nimporte quoi dans ton programme, mais surtout le faire crasher.
 
Normalement, tu ne devrais pas avoir de "magic numbers", comme ton tableau de 22 caractères dans la même fonction ou ton "+10" pour le buffer.
 
Après, j'ai pas tout relu, loin de là. Il faudrait que tu apprennes à te servir de ton debugger, pour ce genre de chose, ca t'aidera grandement pour le développement de tes programmes suivants. J'imagine que vous avez eu un bref cours sur gdb si on vous fait programmer sous solaris. Il va être temps de s'en servir (sinon, tu trouveras de la doc sur le net ...)


---------------
last.fm
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed