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

  FORUM HardWare.fr
  Programmation
  C++

  peut on passer une methode en parametre ?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

peut on passer une methode en parametre ?

n°287072
karim63
Posté le 15-01-2003 à 20:45:09  profilanswer
 

par exemple je voudrais faire ça:
 
j'ai un type liste deja defini d'objet de type O.
 
liste<O> l;
 
O& cherche(int x, (aucune idée du type) fget )
{
O obj;
for(int i=1;i<=tailleliste;i++)
{
  obj=l[i];
  if (x==obj.fget()) {return obj;};
};
 
ça donnerait:
 
O* po= & l.cherche(5,getx());
 
Y a pas moyen de faire un truc dans le style ?

mood
Publicité
Posté le 15-01-2003 à 20:45:09  profilanswer
 

n°287074
antp
Super Administrateur
Champion des excuses bidons
Posté le 15-01-2003 à 20:51:49  profilanswer
 

en C++Builder y a moyen mais ça n'a pas l'air standard du tout :D  
(pour émuler les procedure/function of object du Pascal)


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
n°287080
Captain ad​-hoc
miam les bon batonnets de tux
Posté le 15-01-2003 à 20:58:50  profilanswer
 

avec des pointeurs de fonction membre, je dirais..
un truc du genre
 

Code :
  1. O& cherche(int x, void (O::* fget)())
  2. ...
  3.   if (x==((&obj)->fget)()) {...}

 
 
à tester..

n°287082
wouatouwou​atou
Posté le 15-01-2003 à 21:04:30  profilanswer
 

il est possible de passer une fonction en parametre..;mais men rappelle plus comment kon fait.. mais c possible :D
 
Par contre, une methode.. faut voir... peut etre oui.. peut etre non :p

n°287222
Musaran
Cerveaulté
Posté le 16-01-2003 à 05:10:46  profilanswer
 

Ça devrait donner ça:

Code :
  1. O* liste::cherche(int x, int (liste::*pget)() ) const
  2. {
  3. for(int i=1 ; i<= tailleliste ; i++)
  4.  if ( x == (liste[i].*fget()) )
  5.   return &liste[i];
  6. return NULL; //chou blanc
  7. }
  8. liste<O> l;
  9. O* po= & l.cherche(5, &liste::getx); //obligé de répéter liste:: en argument.


 
Voici le prédicat générique:

Code :
  1. struct A{
  2. int i;
  3. int geti(){ return i;}
  4. };
  5. //vrai si le membre *pmem de l'objet obj vaut value
  6. template <
  7. typename T_Obj, //le type de l'objet
  8. typename T_Mem  //le type du membre de l'objet
  9. >
  10. bool mem_val_tester(
  11. const T_Mem& value //valeur de membre
  12. T_Mem T_Obj::*pmem, //pointeur de membre
  13. const T_Obj obj, //Objet
  14. ){
  15. return obj.*pmem == value;
  16. }
  17. //vrai si l'accesseur *pacc  de l'objet obj renvoie value
  18. template <
  19. typename T_Obj, //le type de l'objet
  20. typename T_Mem  //le type renvoyé par l'acesseur
  21. >
  22. bool acc_val_tester(
  23. const T_Mem& value //valeur de renvoi
  24. T_Mem (T_Obj::*pacc)(), //pointeur d'accesseur
  25. const T_Obj obj, //Objet
  26. ){
  27. return (obj.*pacc)() == value;
  28. }
Code :
  1. int main(){
  2. A a= {7};
  3. bool b1= mem_val_tester(7, &A::   i, a);
  4. bool b2= acc_val_tester(7, &A::geti, a);
  5. }

Il y a peut-être moyen de surcharger un même nom, mais mon compilateur n'en veut pas.
 
Si tu veux l'utiliser comme prédicat pour les algorithmes stl, démerde-toi.
(Il faut jouer avec des adaptateurs bind1st imbriqués, tu veux vraiment qu'on creuses ça ?)


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°287235
karim63
Posté le 16-01-2003 à 07:51:16  profilanswer
 

je vais voir ça cet apres midi.
Sinon si ça peut generecisé mon code et m'eviter de faire une fonction de recherche par objet et par attribut ça m'arrangerait. :)

n°287245
botman
Cubeur
Posté le 16-01-2003 à 08:17:24  profilanswer
 

wouatouwouatou a écrit :

il est possible de passer une fonction en parametre..;mais men rappelle plus comment kon fait.. mais c possible :D
 
Par contre, une methode.. faut voir... peut etre oui.. peut etre non :p

une methode, c'est aussi une fonction, donc tu la passes en pointeur et c'est regle ....


---------------
"OCPLB : On Casse Pas Le Binôme, 'moiselle Jade, Carlson & Peters, page 823 !"
n°287278
antp
Super Administrateur
Champion des excuses bidons
Posté le 16-01-2003 à 09:30:28  profilanswer
 

BotMan a écrit :

une methode, c'est aussi une fonction, donc tu la passes en pointeur et c'est regle ....


 
hum une méthode c'est une fonction qui a un param en plus : le pointeur vers l'objet auquel appartient la méthode (this)


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
n°288022
Musaran
Cerveaulté
Posté le 17-01-2003 à 05:37:34  profilanswer
 

Les pointeurs sur membres sont plus complexes: ils ont le double type de l'objet et du membre.
 
Allons-y:

Code :
  1. //patron de classe fonction prédicat unaire par membre (ouf)
  2. template <typename T_Obj,typename T_Mem>
  3. struct functor_mem_val_tester{
  4. T_Mem T_Obj::*pmem_; //pointeur de membre T_Mem dans un objet T_Obj
  5. T_Mem value_; //valeur à comparer
  6. functor_mem_val_tester( //construire avec...
  7.  T_Mem T_Obj::*pmem, //...le membre et...
  8.  const T_Mem& value) //... la valeur.
  9.  :pmem_ (pmem )
  10.  ,value_(value)
  11. {}
  12. bool operator()(const T_Obj& object){ //tester avec un objet
  13.  return object.*pmem_ == value_; //le test est ici !
  14. }
  15. };
  16. //patron de classe fonction prédicat unaire par accesseur (re-ouf)
  17. template <typename T_Obj,typename T_Mem>
  18. struct functor_acc_val_tester{
  19. T_Mem (T_Obj::*pacc_)(); //pointeur d'accesseur
  20. T_Mem value_; //valeur à comparer
  21. functor_acc_val_tester(T_Mem (T_Obj::*pacc)(), const T_Mem& value): //construire avec l'accesseur et la valeur
  22.                              pacc_ (pacc)  ,       value_(value)
  23. {}
  24. bool operator()(const T_Obj& object){
  25.  return (object.*pacc_)() == value_;
  26. }
  27. };


Exemple:

Code :
  1. #include <functional>
  2. using namespace std;
  3. int main(){
  4. A a= {7};
  5. bool b1= mem_val_tester(7, &A::   i, a);
  6. bool b2= acc_val_tester(7, &A::geti, a);
  7. //objets fonction comparant A::i à 7
  8. functor_mem_val_tester<A,int> mymemtest(&A::   i, 7); //par membre
  9. functor_acc_val_tester<A,int> myacctest(&A::geti, 7); //par accesseur
  10. //test simple
  11. bool b3= mymemtest(a);
  12. bool b4= myacctest(a);
  13. A array[5]= {1,2,3,4,5};
  14. //prédicat utilisé en stl
  15. A* pA1= find_if(&array[0], &array[5], mymemtest );
  16. A* pA2= find_if(&array[0], &array[5], myacctest );
  17. //mymemtest.pmem= &A::j; //possibilité de changer le membre testé
  18. //création du test sur place
  19. A* pA3= find_if(&array[0], &array[5], functor_mem_val_tester<A,int> (&A::   i, 7) );
  20. A* pA4= find_if(&array[0], &array[5], functor_acc_val_tester<A,int> (&A::geti, 7) );
  21. return 0;
  22. }


C'est quoi le prochain truc que tu vas demander :pt1cable: ?


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°292114
karim63
Posté le 22-01-2003 à 19:09:37  profilanswer
 

J'ai du mal a comprendre cette notation :  T_Obj::*pmem

mood
Publicité
Posté le 22-01-2003 à 19:09:37  profilanswer
 

n°292301
Musaran
Cerveaulté
Posté le 23-01-2003 à 05:26:55  profilanswer
 

Les pointeurs de membre (on va dire pm) ne sont pas comme les autres pointeurs des adresses, ce sont des offset: distance entre le membre et le début de l'objet.
 
::* est l'opérateur utilisé pour déclarer un pm.
.* est l'opérateur utilisé pour suivre un pm

Code :
  1. T_Mem var; //variable du même type que le membre
  2. T_Mem *pvar; //pointeur sur une variable du même type que le membre
  3. T_Mem T_Obj::*pmem; //'pointeur' de membre de type T_Mem dans un objet T_Obj
  4. Obj.*pmem; //'indirection' d'un pm sur un objet


Mais pourquoi le type de l'objet fait-il partie du type du pm ?
C'est parce que les pm supportent le mécanisme virtuel.
Il leur est donc nécessaire de savoir à quel type d'objet ils s'appliquent, pour savoir s'il le virtuel s'applique, et si c'est le cas où se trouve le pointeur de table virtuelle (invisible).
 
C'est chaud tout ça... je n'ai compris que récemment.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°292302
gilou
Modérateur
Modzilla
Posté le 23-01-2003 à 05:49:09  profilanswer
 

[:plat00n][:plat00n][:plat00n][:plat00n][:plat00n]


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°292368
karim63
Posté le 23-01-2003 à 09:57:09  profilanswer
 

J'ai reussit a l'implementer et c'est vraiment supper pratique, ça m'arrange vraiment.
Par contre j'ai reussit a faire une fonction qui prend un membre en parametre, mais pas reussit a faire en sorte que cette même fonction appelle une autre fonction qui prend un membre en paramtre. (le même parametre en fait).
Je vois pas comment  faire passer le bidule.
 
J'aurais voulu que search member appelle test_member pour la comparaison, mais j'ai pas reussit.
Ce que je tente de faire va sans doute etre discuté par crtaines personnes, mais spa grave :D
J'ai du mal avec les const etc.
 

Code :
  1. template<class T_Obj,class T_Mem>
  2. bool test_member(T_Mem value,T_Mem (T_Obj::*pacc)(),T_Obj obj)
  3. {
  4.   return (obj.*pacc)()==value;
  5. };
  6. template<class T_Obj,class T_Mem>
  7. Plist<int> search_member(T_Mem value,T_Mem (T_Obj::*pacc)(),Plist<T_Obj> &l)
  8. {
  9.   Plist<int> r;
  10.   int n=l.getsize();
  11.   if (n>0)
  12.     {
  13.       Pnode<T_Obj>* f = l.getnode(1);
  14.       for(int i=1;i<=n;i++)
  15. {
  16.   if  ((f->getinfo()->*pacc)()==value)
  17.     {
  18.    
  19.       r.adde(new int (i));
  20.     };
  21.   f=f->getnext();
  22.  };
  23.     };
  24.   return r;
  25. };


Message édité par karim63 le 23-01-2003 à 09:59:58
n°292370
farib
Posté le 23-01-2003 à 10:00:50  profilanswer
 

:sol:  :sol:  :sol:  :sol:  :D merci pour moi

n°292379
Taz
bisounours-codeur
Posté le 23-01-2003 à 10:20:37  profilanswer
 

personne n'a palé des memfun?  
 
http://www.sgi.com/tech/stl/mem_fun_t.html
 
c'est plus simple à mon avis :hello:

n°292425
gilou
Modérateur
Modzilla
Posté le 23-01-2003 à 11:10:05  profilanswer
 

farib a écrit :

:sol:  :sol:  :sol:  :sol:  :D merci pour moi


C'etait pour la geniale clarification de Musaran precedent mon post.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°293034
Musaran
Cerveaulté
Posté le 24-01-2003 à 09:03:24  profilanswer
 


Si ça continues je vais y prendre goût.
Tu sais qu'on a droit à 10 smileys par post :o ?
 
Après réflexion je peut étoffer l'explication, on reprends:
????
Les pointeurs de membre (on va dire pm) ne sont pas comme les autres pointeurs des adresses, ce sont des offset: distance entre le membre et le début de l'objet.
 
Les opérateurs de membre:

Code :
  1. ::  //pour spécifier un membre
  2. ::* //pour déclarer un pm.
  3. .* //pour 'suivre' un pm sur un objet
  4. ->* //pour 'suivre' un pm sur/via un pointeur d'objet


Base de travail

Code :
  1. typedef int T_Mem;
  2. struct T_Obj{
  3. T_Mem mdat;                      //membre
  4. T_Mem mfun(){return this->mdat;} //accesseur
  5. };
  6. T_Obj Obj; //objet
  7. T_Mem var; //variable du même type que le membre


Exemple

Code :
  1. //pointeur classique
  2. T_Mem *pvar; //pointeur sur une variable du même type que le membre
  3. pvar= &var; //initialisé avec une adresse de variable n'importe où en mémoire
  4. *pvar; //suivre le pointeur, retrouve var
  5. //pointeur de membre de données
  6. T_Mem   T_Obj::*pmdat; //'pointeur' de membre de type T_Mem dans un objet T_Obj
  7. pmdat= &T_Obj::mdat; //initialisé avec un offset de membre dans T_Obj (ou parent) exclusivement
  8.           Obj.*pmdat; //'suivre' l'offset, retrouve mdat
  9. //pointeur de membre méthode
  10. T_Mem  (T_Obj::*pmfun)(); //'pointeur' de méthode renvoyant T_Mem dans un objet T_Obj
  11. pmfun= &T_Obj::mfun; //initialisé avec une adresse de fonction
  12.          (Obj.*pmfun)(); //'suivre' l'offset et appeler la méthode
  13. //Les mêmes mis en parallèle
  14. T_Mem         *pvar    = &var         ;      *pvar     ; //variable
  15. T_Mem  T_Obj::*pmdat   = &T_Obj::mdat ;  Obj.*pmdat    ; //membre de données
  16. T_Mem (T_Obj::*pmfun)()= &T_Obj::mfun ; (Obj.*pmfun)() ; //méthode. Parenthèses car .* est moins prioritaire que ()


Le pm ne se déréférence qu'associé avec un objet.
Normal: c'est un décalage sur quelque chose.
 
Mais pourquoi le type de l'objet fait-il partie du type du pm ?
1) La sécurité de type à la compilation.
Si on pouvait appliquer le pm à n'importe quel objet, il n'y aurait pas forcément le bon membre au bon offset.
 
2) Parce que les pm supportent le mécanisme virtuel.
Il leur est donc nécessaire de savoir à quel type d'objet ils s'appliquent, pour savoir s'il le virtuel a lieu, et si c'est le cas où se trouve le pointeur de table virtuelle (invisible).
 
Pour ces raisons, le pm méthode subit les contraintes d'un membre. Alors que c'est une adresse globale de fonction (comme un pointeur banal), puisque les fonctions ne sont pas physiquement dans l'objet.
????
 
C'est plus long mais mieux détaillé... c'est bon ou pas ?
 
 
karim63:

Code :
  1. if  ((f->getinfo()->*pacc)()==value)

À priori c'est comme ça:

Code :
  1. if ( test_member(value, pacc, *(f->getinfo()) ) )

Mais je teste pas.
 
 

++Taz a écrit a écrit :

personne n'a palé des memfun?



Je crois que c'est pas compatible avec ça:

Citation :

eviter de faire une fonction de recherche par objet et par attribut

Enfin je suis pas sûr là...
 
C'est de plus en plus [:ciler] ce qu'on fait ici.
 
Ah au fait, les "adaptateurs bind1st imbriqués" ne peuvent pas marcher directement, vu que ces adaptateurs ne manipulent que des fonctions à deux argument.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°293043
gilou
Modérateur
Modzilla
Posté le 24-01-2003 à 09:18:03  profilanswer
 

Nous disons donc 10 smileys? voilà, voilà!
 
[:plat00n]  
[:plat00n][:plat00n]  
[:plat00n][:plat00n][:plat00n] [:plat00n]
[:plat00n][:plat00n]
[:plat00n]
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --

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

  peut on passer une methode en parametre ?

 

Sujets relatifs
methode mkdirs de la classe File ou Droits avec apache et tomcat[PHP] Faire un test sur la valeur d'un paramètre du php.ini
[php] probleme bizarre de passage de parametre--enable-trans-sid activé / Empecher le SID de passer dans l'url?
Pg_Fetch_Row ???? C'est quoi le parametre int row ?Passer un dump de postresql a mysql
Script bash: accéder au dernier paramètreASP : Passer une chaine de caractere en MAJUSCULE ?
Appeler un script PHP avec parametre depuis un lien HTML[PHP et SQL] passage de variable en parametre
Plus de sujets relatifs à : peut on passer une methode en parametre ?


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