Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2410 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Probleme de surcharge d'opérateur et de fonction amies

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Probleme de surcharge d'opérateur et de fonction amies

n°1616287
titeuf789
Posté le 27-09-2007 à 18:32:47  profilanswer
 

Bonjour, j'aurais besoin d'explication pour mon programme. Voici la situation , j'aimerais en gros réaliser les operations suivantes :
 

Code :
  1. /*******************************test.cc***********************/
  2. Longueur L(100); 
  3. Temps T (10); 
  4. Vitesse V (40);
  5. double d;
  6. L= V * T;    ==>ok
  7. V = V * 2;  ==>ne marche pas
  8. V = V * V  ==>ok
  9. V = 2 * V;  ==>ok
  10. d = V * V;  ==>ne marche pas


 
J'ai donc deux problémes que je n'arrive pas à résoudre, voici mon code :  
 

Code :
  1. /*******************************grandeur.h***********************/
  2. template <typename TYPE>
  3. class Grandeur{
  4. Grandeur(double tval=0):val(tval){};
  5. public:
  6.   Grandeur(double tval=0):val(tval){};
  7.   inline double getVal() const{
  8.     return val;
  9.   }
  10.   friend inline TYPE operator * (const TYPE& t1,const TYPE& t2){
  11.     return TYPE(t1.val * t2.val);
  12.   }
  13. protected:
  14.   double val;
  15. };
  16. class Longueur : public Grandeur<Longueur>{
  17. public:
  18. Longueur(double tval=0):Grandeur<Longueur>(tval){}
  19. };
  20. class Temps : public Grandeur<Temps>{
  21. public:
  22. Temps(double tval=0):Grandeur<Temps>(tval){}
  23. };
  24. class Vitesse : public Grandeur<Vitesse>{
  25. public:
  26. Vitesse(double tval=0):Grandeur<Vitesse>(tval){}
  27.   Longueur operator * (const Temps& t) const;
  28. };
  29. inline Longueur Vitesse::operator * (const Temps& t) const{
  30.   return Longueur(val * t.getVal());
  31.   }


 
 
Déjà je ne comprend pas vraiment pourquoi V = 2 * V me rend un resultat correct puisque d'apres ce que j'ai compris une classe fille ne peut pas se servir des fonctions amies de la classe mére ??? mais il me fallait des fonctions non membre pour réaliser cette opération.
 
Pour V = V * 2 par contre, le compilateur me sort :
 
 erreur: ambiguous overload for ‘operator*’
 note: candidats sont: Longueur Vitesse::operator*(const Temps& ) const
 note:                 Vitesse operator*(const Vitesse&, const Vitesse& )
 
Le nombre ne connait donc pas son type de convertion, c'est donc mon modéle qui est faux mais je ne voit pas comment organiser les choses différemment. Je pensais a surcharger l'operateur de convertion des doubles sinon, dans la classe générique :
 
 

Code :
  1. TYPE operateur double(){
  2.     return TYPE(val);
  3.   }


 
mais le compilateur n'aime pas apparemment ...
 
Le dernier test d = V * V reste un mystére, j 'ai l'erreur suivante :
erreur: cannot convert ‘Vitesse’ to ‘double’ in assignment
 
Je ne comprend pas pourquoi le double n'est pas transformer en une instance de Vitesse, puisqu'il le fait très bien lors de la multiplication 2*V , j'ai donc essayé de réécrire l'opérateur d'affectation mais toujours rien ...
 
Donc voilà je ne sais plus trop quoi faire et une petite aide serait la bien venue, merci d'avance  
 

mood
Publicité
Posté le 27-09-2007 à 18:32:47  profilanswer
 

n°1616293
KangOl
Profil : pointeur
Posté le 27-09-2007 à 19:08:09  profilanswer
 

[icode]operator double()[/icode] doit renvoyer un double
 
ca reglera ton dernier test...
 
----
note: pour la balise, http://kangol.prout.be/gm/md_inlinecode.user.js

n°1616296
titeuf789
Posté le 27-09-2007 à 19:20:34  profilanswer
 

ca régle quoi en fait ? je comprend pas trop le principe

n°1616299
KangOl
Profil : pointeur
Posté le 27-09-2007 à 19:25:05  profilanswer
 

bha vu que tu lui dit comment convertir en double, il le sais ...

n°1616300
titeuf789
Posté le 27-09-2007 à 19:31:36  profilanswer
 

mais en fait ce que je voulais en faisant ça c'était de contourner l'ambiguitée qu'il y avait en transformant un double en un élément de la classe fille , ca ne m'intéresse pas de convertir en double . Je dois m'être mal organisé dans l'héritage ou je ne sais quoi, je bloque complétement ...

n°1616301
KangOl
Profil : pointeur
Posté le 27-09-2007 à 19:37:55  profilanswer
 

fais des typedef, ca ira plus vite :o

n°1616305
titeuf789
Posté le 27-09-2007 à 19:46:32  profilanswer
 

ou ca des typedef ?

n°1616309
Joel F
Real men use unique_ptr
Posté le 27-09-2007 à 19:58:02  profilanswer
 

tu me copieras 10000 fois :
 
"les operateurs binaires ne s'implantent pas comme des fonctions firends masi comme des fonctiosn libres" :o

n°1616312
Ace17
Posté le 27-09-2007 à 20:03:34  profilanswer
 

Joel F a écrit :

tu me copieras 10000 fois :
 
"les operateurs binaires ne s'implantent pas comme des fonctions firends masi comme des fonctiosn libres" :o


Et pourquoi pas des friends?

n°1616314
titeuf789
Posté le 27-09-2007 à 20:06:06  profilanswer
 

mais je suis obliger de faire appel a une fonction non membre , sinon je ne peut pas résoudre l'opération V = 2 * V par exemple , j'ai vu ca sur ce site :
http://www.emse.fr/~boissier/ensei [...] non-membre  
 
ça avais l'air d'être des cours donc bon ...

mood
Publicité
Posté le 27-09-2007 à 20:06:06  profilanswer
 

n°1616349
Joel F
Real men use unique_ptr
Posté le 27-09-2007 à 22:51:34  profilanswer
 

Ace17 a écrit :


Et pourquoi pas des friends?


 
parce que les operateurs binaires de type +-*/ sont symmétriques. Dans a+b, a n'a pas de rôle à jouer face à b, ca elimine d'office la fonction memebre. Reste donc fonction libre ou amie.  
La Fonction ami pete l'encapsulation alors que la fonction libre suffit a faire ce dotn tu as besoin en utilisant les accesseurs/mutateurs qui vont bien.
 
Quant à V =2*V ... faudra voir à mettre des ocnstructeurs explicites, écrire une Forme Canonique de Coplien et a pas utiliser le Bartman&Norton's Trick quand on sait pas s'en servir à bon escient.
 
Ah ouais, et pour preparer vendredi, ce cours est à chier :o
 
une version g++ compliant :
 

Code :
  1. #include <iostream>
  2. using namespace std;
  3. template <typename TYPE> class Grandeur
  4. {
  5.   public:
  6.   Grandeur(double tval=0):val(tval){};
  7.   inline double getVal() const{ return val; }
  8.   protected:
  9.   double val;
  10. };
  11. class Longueur : public Grandeur<Longueur>
  12. {
  13.   public:
  14.   Longueur(double tval=0):Grandeur<Longueur>(tval){}
  15.   Longueur(const Grandeur<Longueur>& src):Grandeur<Longueur>(src.getVal()){}
  16. };
  17. class Temps : public Grandeur<Temps>
  18. {
  19.   public:
  20.   Temps(double tval=0):Grandeur<Temps>(tval){}
  21.   Temps(const Grandeur<Temps>& src):Grandeur<Temps>(src.getVal()){}
  22. };
  23. class Vitesse : public Grandeur<Vitesse>
  24. {
  25.   public:
  26.   Vitesse(double tval=0):Grandeur<Vitesse>(tval){}
  27.   Vitesse(const Grandeur<Vitesse>& src):Grandeur<Vitesse>(src.getVal()){}
  28. };
  29. template<class T1,class T2> struct unit;
  30. template<class T> struct unit<T,T>    { typedef T type; };
  31. template<> struct unit<Temps,Vitesse> { typedef Longueur type; };
  32. template<> struct unit<Vitesse,Temps> { typedef Longueur type; };
  33. template<class T1,class T2>
  34. Grandeur< typename unit<T1,T2>::type >
  35. operator*( const Grandeur<T1>& t1, const Grandeur<T2>& t2 )
  36. {
  37.   typedef typename unit<T1,T2>::type unit_type;
  38.   typedef Grandeur<unit_type> return_type;
  39.   return return_type( t1.getVal()*t2.getVal() );
  40. }
  41. template<class T>
  42. Grandeur<T> operator*( const double& t1, const Grandeur<T>& t2 )
  43. {
  44.   typedef Grandeur<T> return_type;
  45.   return return_type( t1*t2.getVal() );
  46. }
  47. template<class T> Grandeur<T> operator*( const Grandeur<T>& t1, const double& t2 )
  48. {
  49.   typedef Grandeur<T> return_type;
  50.   return return_type( t1.getVal()*t2 );
  51. }
  52. int main()
  53. {
  54.   Longueur L(100);
  55.   Temps T (10);
  56.   Vitesse V (40);
  57.   Longueur L2 = V*T;
  58.   cout << L2.getVal() << endl;
  59.   V = V*2;
  60.   cout << V.getVal() << endl;
  61.   V = 0.5*V;
  62.   cout << V.getVal() << endl;
  63. }


 
Ensuite tu m'expliqueras comme Vitesse*Vitesse ca donne un double OU une vitesse au carré, c'est pas homogène :o

n°1616351
Ace17
Posté le 27-09-2007 à 23:19:01  profilanswer
 

Joel F a écrit :


parce que les operateurs binaires de type +-*/ sont symmétriques. Dans a+b, a n'a pas de rôle à jouer face à b, ca elimine d'office la fonction memebre. Reste donc fonction libre ou amie.  

Jusque-la, je suis completement d'accord avec toi.
 

Joel F a écrit :


La Fonction ami pete l'encapsulation alors que la fonction libre suffit a faire ce dotn tu as besoin en utilisant les accesseurs/mutateurs qui vont bien.

Je ne vois pas en quoi la fonction amie "pete" l'encapsulation ... peux-tu me donner un exemple ou l'emploi des fonctions amies est justifie, dans ce cas? N'existe-t-il pas des cas ou un operateur binaire doit manipuler des membres prives auquels il serait peu judicieux de donner acces, meme a travers un accesseur?  

n°1616354
IrmatDen
Posté le 27-09-2007 à 23:26:45  profilanswer
 

Ace17 a écrit :

Je ne vois pas en quoi la fonction amie "pete" l'encapsulation ... peux-tu me donner un exemple ou l'emploi des fonctions amies est justifie, dans ce cas? N'existe-t-il pas des cas ou un operateur binaire doit manipuler des membres prives auquels il serait peu judicieux de donner acces, meme a travers un accesseur?  


Je pense que c'est comme tu dis: 'des cas'. Donc à n'utiliser que lorsque l'usage y est strictement nécessaire... à mon avis.

n°1616369
titeuf789
Posté le 28-09-2007 à 00:05:39  profilanswer
 

Franchement c'est ingénieux comme truc j'aurais jamais pensé a une implémentation comme ça, pour Vitesse*Vitesse ça devrait rendre un double mais je pense que je m'en sortirais. Je te remercie parce que j'étais vraiment bloqué

n°1616424
Joel F
Real men use unique_ptr
Posté le 28-09-2007 à 08:57:36  profilanswer
 

IrmatDen a écrit :


Je pense que c'est comme tu dis: 'des cas'. Donc à n'utiliser que lorsque l'usage y est strictement nécessaire... à mon avis.


 
C'est exactement ça. Si tu peut pas faire autrement, vas y fait une fonction amie. Mais, à l'usage, tu t'apercevra que, dans 99.999999932648% des cas,
t'en a pas besoin car tu as ta pelleté d'accesseur/mutateur.
 
@titeuf789 : je comprends pas pkoi vitesse*vitesse ca devrait renvoyer un double o_O c'est physiquement incorrect.
 
@le reste :
Pour infos : http://boost.org/libs/mpl/doc/tuto [...] lysis.html
Boost::MPL fournit un exemple avec une implantation plus poussée mais utilisant le même genre d'idée.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Probleme de surcharge d'opérateur et de fonction amies

 

Sujets relatifs
fonction(quelle image est dans mon clip)[easyphp] Probleme d'administration
problème flash cliquable sous IE6probleme de compilation sous KEIL
[RESOLU] Probleme pour augmenter un DIV en fonction d'un autreproblème XMLBeans sous eclipse
probléme gotoAndPlayC++ openGL problème couleur
fonction poll() en C sous linux 
Plus de sujets relatifs à : Probleme de surcharge d'opérateur et de fonction amies


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR