Probleme(s) sur les Template

Probleme(s) sur les Template - C++ - Programmation

Marsh Posté le 08-12-2009 à 19:25:01    

Bonsoir tout le monde,
 
j'ai une classe Fraction (qui fait partie d'un package Maths) que j'ai du passer en Template, maintenant elle s'appelle FractionG
 
Alors j'ai normalement fait toute les modification adéquate mais le test unitaire de mes surcharges =, ==, != ne fonctionne pas (en prenant l'exemple sur ma MatriceG).
Sinon pour les comparaisons sur des entiers je n'ai pas d'erreur mais il me sort "template class has already been defined" au build
PS : le code qui ne fonctionne pas est en commentaire.
 
voici le code FractionG_2.cpp :  

Code :
  1. //
  2. // IUT de Nice / Departement informatique / Module APO-C++
  3. // Annee 2009_2010 - Feuille_6
  4. //
  5. // Classe FractionG : Surcharge opérateurs =, ==, !=
  6. //
  7. // Auteurs : C. Mus & S. Funel
  8. //
  9. #ifndef _FractionG
  10. #include "FractionG.h"
  11. #endif
  12. // --- Surcharge de l'opérateur = avec une FractionG
  13. //
  14. template <class G>
  15. FractionG <G> &FractionG <G>::operator =(const FractionG& f) {
  16. m_numerateur= f.m_numerateur ;
  17. m_denominateur= f.m_denominateur ;
  18. return *this ;
  19. }
  20. // --- Surcharge de l'opérateur = avec un entier
  21. //
  22. template <class G>
  23. FractionG <G> &FractionG <G>::operator =(int op) {
  24. m_numerateur= op ;
  25. m_denominateur= 1 ;
  26. return *this ;
  27. }
  28. // --- Surcharge de l'opérateur == comparaison entre deux FractionGs
  29. //
  30. template <class G>
  31. bool FractionG <G>::operator ==(const FractionG& f) {
  32.    // Controler les produits croisés
  33.    //
  34.    return numerateur()*f.denominateur() == f.numerateur()*denominateur(); // Edit, Erreur corrigé
  35. }
  36. // --- Surcharge de l'opérateur == comparaison entre une FractionG et un entier
  37. //
  38. template <class G>
  39. bool FractionG <G>::operator ==(int op) {
  40.    // Controler le produit croise
  41.    //
  42.    return numerateur() == op*denominateur();
  43. }
  44. // --- Surcharge de l'opérateur != comparaison entre deux FractionGs
  45. //
  46. template <class G>
  47. bool FractionG <G>::operator !=(const FractionG& f) {
  48.    // Controler le produit croise
  49.    //
  50. return numerateur()*f.denominateur() != f.numerateur()*denominateur();
  51. }
  52. // --- Surcharge de l'opérateur != comparaison entre une FractionG et un entier
  53. //
  54. template <class G>
  55. bool FractionG <G>::operator !=(int op) {
  56.    // Controler le produit croise
  57.    //
  58.    return numerateur() != op*denominateur();
  59. }


 
Et voici mon test unitaire :  

Code :
  1. //
  2. // IUT de Nice / Departement informatique / Module APO-C++
  3. // Annee 2009_2010 - Package _Maths
  4. //
  5. // Classe FractionG - Tests unitaires des operateurs == et !=  
  6. //                   (cas nominaux)
  7. //
  8. // Auteur : S. Funel & C. Mus
  9. //
  10. #ifndef _FractionG_
  11. #include "..\_SRC\FractionG.h"
  12. #endif
  13. #include "..\_SRC\FractionG.cpp"
  14. #include "..\_SRC\FractionG_2.cpp"
  15. #include "T:\_Tests\Tests\Tests.h"
  16. void main () {
  17.    Tests::Begin("_Maths.FractionG", "2.0.0" );
  18.       Tests::Design("Controle des operateurs (Premiere partie)", 3);
  19.          /*Tests::Case("Operateur == : comparaison de deux FractionG" ); {
  20.          
  21.      FractionG f1(3,3);
  22.   Fraction f2(5), f3(-3), f4(6);
  23.   int f5(2,1), f6(12,6), f7(3,1), f8(-3,1);
  24.   int f9(10,5), f10(-10,-5);
  25.             Tests::Unit(0,  f1==f2);
  26.             Tests::Unit(1,  f3==f4);
  27.             Tests::Unit(1,  f5==f6);
  28.             Tests::Unit(0,  f7==f8);
  29.             Tests::Unit(0,  f9==f10);
  30.   Tests::Unit(1,  f2==f9);
  31.          }*/
  32.          Tests::Case("Operateur == : comparaison avec un entier" ); {
  33.   int f1(2),  f2(-2), f3(0), f4(0);
  34.             Tests::Unit(1,  f1==2);
  35.             Tests::Unit(1,  f2==-2);
  36.             Tests::Unit(1,  f3==0);
  37.             Tests::Unit(0,  f4==-1);
  38.          }
  39.          /*Tests::Case("Operateur != : comparaison de deux FractionGs" ); {
  40.   int f1(2),  f2(7), f3(-2), f4(2);
  41.   int f5(2), f6(-4), f7(1), f8(1);
  42.             Tests::Unit(1,  f1!=f2);
  43.             Tests::Unit(1,  f3!=f4);
  44.   Tests::Unit(0,  f4!=f5);
  45.             Tests::Unit(1,  f5!=f6);
  46.             Tests::Unit(0,  f7!=f8);
  47.          }*/
  48.      
  49.          Tests::Case("Operateur != : comparaison avec un entier" ); {
  50.   int f1(2),  f2(4), f3(-1), f4(-1);
  51.             Tests::Unit(0,  f1!=2);
  52.             Tests::Unit(1,  f2!=-2);
  53.             Tests::Unit(1,  f3!=0);
  54.             Tests::Unit(0,  f4!=-1);
  55.          }
  56.       Tests::Design("Controle des operateurs (Deuxieme partie)", 3);
  57.          /*Tests::Case("Operateur = : cas de deux FractionGs" ); {
  58.          FractionG& <FractionG> f1(2,3),  f2(5,4);
  59.          FractionG& <FractionG> f(0);
  60.             f=f1;  Tests::Unit(1, f==f1);
  61.                    Tests::Unit(0, f==f2);
  62.             f1=f2; Tests::Unit(0, f1==f);
  63.                    Tests::Unit(1, f1==f2);
  64.          }
  65.          Tests::Case("Operateur = : cas d'un entier" ); {
  66.          FractionG& <FractionG> f(-1);
  67.             f=0; Tests::Unit(0, f==1);
  68.                  Tests::Unit(1, f==0);
  69.                  Tests::Unit(1, f==-0);
  70.             f=7; Tests::Unit(0, f==0);
  71.                  Tests::Unit(1, f==7);
  72.          }
  73. */
  74.    Tests::End();
  75. }


 
Merci beaucoup d'avance.
 
Philip Masse


Message édité par Philip Masse le 09-12-2009 à 09:42:39
Reply

Marsh Posté le 08-12-2009 à 19:25:01   

Reply

Marsh Posté le 08-12-2009 à 20:03:22    

C'est normal le  return <G> ligne 43?


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 08-12-2009 à 20:13:58    

Petite erreur, merci :)
Corrigé !

Reply

Marsh Posté le 08-12-2009 à 22:21:12    

on en mets pas le corps d'un template dans un .cpp mais dans un .h


Message édité par Joel F le 08-12-2009 à 22:21:43
Reply

Marsh Posté le 09-12-2009 à 09:43:58    

Voici le .h
PS : La surcharge du constructeur fonctionne...
 

Code :
  1. //
  2. // IUT de Nice / Departement informatique / Module APO-C++
  3. // Annee 2009_2010 - Package _Maths
  4. //
  5. // Classe FractionG : modelisation du corps ZxZ
  6. //
  7. // Edition A      : TD_4
  8. //    Version 2.0.0   : version initiale
  9. //   
  10. // Auteur : C. Mus & S. Funel
  11. //
  12. #include <stdio.h>
  13. #include <math.h>
  14. #ifndef _Object_
  15. #include "T:\_Archives\Object\Object.h"
  16. #endif
  17. #ifndef _Archive_
  18. #include "T:\_Archives\Archive\Archive.h"
  19. #endif
  20. #ifndef _Archive_
  21. #include "T:\_Archives\_Archives\_Archives.h"
  22. #endif
  23. #define _FractionG_
  24. // Fonctions publiques de servitudes
  25. //
  26. int PGCD (int, int);
  27. int PPCM (int, int);
  28. template <class G> class FractionG {
  29. private :
  30. int m_numerateur;
  31. int m_denominateur;
  32. void  reduire ();
  33. public :
  34. // ------ Constructeurs
  35. //
  36. FractionG () {m_numerateur= 0; m_denominateur=1;}
  37. FractionG(int, int);
  38. FractionG(int);
  39. FractionG(const FractionG& );
  40. // ------ Accesseurs  
  41. //
  42. inline bool ok()  const {return (m_denominateur==0 ? false : true);}
  43. inline bool nok() const {return !ok();}
  44. inline int numerateur()   const {return m_numerateur;}
  45. inline int denominateur() const {return m_denominateur;}
  46. // ------ Operateurs
  47. //
  48. FractionG& operator =(const FractionG& );
  49. FractionG& operator =(int);
  50. FractionG* operator +(const FractionG& );
  51. FractionG* operator +(int);
  52. FractionG& operator +=(const FractionG& );
  53. FractionG& operator +=(int);
  54. FractionG* operator -(const FractionG& );
  55. FractionG* operator -(int);
  56. FractionG& operator -=(const FractionG& );
  57. FractionG& operator -=(int);
  58. FractionG* operator *(const FractionG& );
  59. FractionG* operator *(int);
  60. FractionG& operator *=(const FractionG& );
  61. FractionG& operator *=(int);
  62. FractionG* operator /(const FractionG& );
  63. FractionG* operator /(int);
  64. FractionG& operator /=(const FractionG& );
  65. FractionG& operator /=(int);
  66. bool operator ==(const FractionG& );
  67. bool operator ==(int);
  68. bool operator !=(const FractionG& );
  69. bool operator !=(int);
  70. bool operator <(const FractionG& );
  71. bool operator <(int);
  72. bool operator <=(const FractionG& );
  73. bool operator <=(int);
  74. bool operator >(const FractionG& );
  75. bool operator >(int);
  76. bool operator >=(const FractionG& );
  77. bool operator >=(int);
  78. // ------ Services
  79. //
  80. char* toString() const;
  81. };

Reply

Marsh Posté le 09-12-2009 à 09:59:41    

Ce que Joel dit, c'est que sauf cas particulier (voir http://www.bourguet.org/v2/cpplang/export.pdf), on est force de voir la definition des templates quand on les utilise.  Donc on place la definition dans le .hpp -- directement ou indirectement, j'ai tendance a la mettre un .tpp qui est inclus dans le .hpp, tout comme mes definitions inline sont parfois dans un .ipp.
 
Seconde remarque, utiliser des chemins absolus dans les includes est une mauvaise idee.  Utilise des chemins relatifs (et avec / comme separateur, ca marche sous Windows comme sous Unix) et indique les racines ou chercher a ton compilateur.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 09-12-2009 à 10:03:10    

Pour les chemins c'est normal, on travail tous sur la même base T:
Mais c'est vrai que tu as raison !
 
Sinon je ne vois pas où il y a un problème, pour le faire je me suis calquer sur la MatriceG de fraction qui fonctionne très bien (sauf la persistance).
 
Edit : Le chemins sont absolue dans certain étant donnée qu'on utilise le versioning. j'avais zapper !


Message édité par Philip Masse le 09-12-2009 à 10:52:32
Reply

Marsh Posté le 09-12-2009 à 10:24:08    

Alors, on y va y aller tres lentement:
 
Bien:

Code :
  1. // template.hpp
  2. template<class T> struct foo
  3. {
  4.    void bar() { /* some code; */ }
  5. };


 
PAS Bien:

Code :
  1. // template.hpp
  2. template<class T> struct foo
  3. {
  4.    void bar();
  5. };


 

Code :
  1. //template.cpp
  2. #include "template.hpp"
  3. template<class T> void foo<T>::bar() { /* some code; */ }


 

Reply

Marsh Posté le 09-12-2009 à 10:48:38    

heuuu :s

Reply

Sujets relatifs:

Leave a Replay

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