Mettre une méthode de classe en argument d'une autre méthode

Mettre une méthode de classe en argument d'une autre méthode - C++ - Programmation

Marsh Posté le 26-08-2005 à 16:00:56    

Bonjour,
 
J'ai créé une méthode de classe, nommé solve_eq(...), qui résoud une équation.
 
Je cherche à ce qu'elle prenne comme argument d'entrée des méhodes d'autres classes qui, chacune renvoie un double à partir d'un autre double (typiquement double class_a::carre(double) , double class_b::sinus(double) etc).
 
Je ne suis pas parvenue à conserver une unique méthode solve_eq pour ce problème. J'ai du utiliser la surcharge en définissant plusieurs méthodes solve_eq(...) et passer également par des méthodes statics comme argument (ie. static double class_a::carre(double) , static double class_b::sinus(double) etc) ou des fonctions définies hors de classes.
 
Est ce qu'il est néanmoins possible de ne conserver qu'une unique méthode solve_eq et de mettre en argument des méthodes de classe non static ?

Reply

Marsh Posté le 26-08-2005 à 16:00:56   

Reply

Marsh Posté le 26-08-2005 à 16:43:30    

Tu peux donner un exemple du code que tu aimerais écrire ?


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 27-08-2005 à 13:01:20    

Bon, en fait, il suffit qu'on pose une question, pour que en y réfléchissant, on trouve la réponse. En l'occurence, je pense avoir résolu mon problème par un simple template.
 
J'avais le programme suivant :
 

Code :
  1. #include <iostream>
  2. using namespace std;
  3. class class_A
  4. {
  5. public:
  6.   double sinus(double x)
  7.   {return (sin(x));}
  8. };
  9. class class_B
  10. {
  11. public:
  12.   double cosinus(double x)
  13.   {return (cos(x));}
  14. };
  15. class mes_math
  16. {
  17. public:
  18.    
  19.     double carre(double (class_A::*func)(double),double x)
  20.       {class_A tmp;
  21.       return (((tmp.*func)(x))*((tmp.*func)(x)));}
  22.      
  23.     double carre(double (class_B::*func)(double),double x)
  24.       {class_B tmp;
  25.       return (((tmp.*func)(x))*((tmp.*func)(x)));}
  26. };
  27. int main()
  28. {
  29.   double xa,xb,ya,yb;
  30.   mes_math toto;
  31.   double (class_A::* fonction_A) (double) = & class_A::sinus;
  32.   double (class_B::* fonction_B) (double) = & class_B::cosinus;
  33.   xa = 1.23;
  34.   xb = 4.56;
  35.   ya = toto.carre(fonction_A,xa);
  36.   yb = toto.carre(fonction_B,xb);
  37.   cout << "ya = " << ya << " yb = " << yb << endl;
  38. }


 
Je cherchais à avoir une seule méthode carre de la classe mes_math pour faire le calcul du carré de f(x), où f est la fonction passée en argument.
 
J'ai simplement créée, à la place de mes deux méthodes séparées et surchargées, une seule méthode par un template :
 

Code :
  1. template <class T>
  2.   double carre(double (T::*func)(double),double x)
  3.   {T tmp;
  4.     return (((tmp.*func)(x))*((tmp.*func)(x)));}


 
et ça marche !
 
Y a t-il mieux ? Est ce que ce genre de code est suffisamment propre pour ce que je veux faire ?

Reply

Marsh Posté le 27-08-2005 à 13:02:06    

f est la méthode passée en argument évidemment, pas la fonction !

Reply

Marsh Posté le 27-08-2005 à 18:36:14    

nathan_g a écrit :


Y a t-il mieux ? Est ce que ce genre de code est suffisamment propre pour ce que je veux faire ?


 
On peut probablement faire mieux, tant au point de vue conception, réutilisabilité, que performance.
Ta fonction template carre, je l'appelerai plutot compose_carre_with, ce qui est le cas d'école de la mauvaise conception que l'on qualifie dans la littérature, de "blob" (j'en ignore l'origine). carre(x), c'est x * x, et ça ne dépend pas d'une fonction que l'on applique au préalable à x.
 
Ensuite, tes fonctions membres sinus et cosinus, elles ont this const, en toute rigeur. Regarde ce que ça implique ...
 
En fait, je te conseillerais plutot de faire un foncteur Cosinus, Sinus, et de les invoquer en tant que paramètre générique dans ta fonction de résolution d'équations (ou carré ...). Sans oublier de mettre en paramètre générique le type que tu utilises, double ici.
 
Question performances, l'appel de fonctions membres via pointeur, on peut réver mieux. Surtout qu'avec ta façon de composer les fonctions, en plus de perdre en réutilisabilité, ben tu fais peut etre 2 appels.

Reply

Marsh Posté le 29-08-2005 à 17:44:11    

Pourquoi utiliser une variable inutile tmp (-> fonction statique) ? Pourquoi utiliser des classes (-> simples fonctions ?) ?
En général on passe plutot la fonction en paramètre template => tu paramétrises l'algorithme.

Code :
  1. double sinus( double x )
  2. {
  3.     return std::sin( x );
  4. }
  5. double cosinus( double x )
  6. {
  7.     return std::cos( x );
  8. }
  9. typedef double (*my_functor)( double );
  10. template<my_functor F>
  11. double carre( double x )
  12. {
  13.     return F( x ) * F( x );
  14. }
  15. int main()
  16. {
  17.     carre<&sinus>( 1.0 );
  18.     carre<&cosinus>( 1.0 );
  19. }


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 29-08-2005 à 20:25:17    

c'est laid, 2 vrais solutions :
-> les foncteurs
-> les expressions templates
 
La solution de HelloWorld est pas mal aussi :)
Mais les & sont inutiles ;)


Message édité par Joel F le 29-08-2005 à 20:25:55
Reply

Sujets relatifs:

Leave a Replay

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