[VC++] Pointeur de fonction : au secours !

Pointeur de fonction : au secours ! [VC++] - C++ - Programmation

Marsh Posté le 04-05-2004 à 11:41:36    

Bon... Je suis mauvais :cry:  
J'ai besoin d'un pointeur de fonction, mais pas moyen de m'en sortir :pt1cable:  
 
[En gros]
J'ai une classe A qui en instancie une autre B. La classe B ne connait rien de la classe A.
Je souhaite passer un pointeur sur une des fonctions de A à B, cette fonction n'étant pas statique.
[/En gros]
 
J'ai un truc dans ce genre là :
 

Code :
  1. class CPageBidule : public CDialog
  2. {
  3. ...
  4. public:
  5.   void SetEtatMachin(CDialogMachin::ETAT etat);
  6. private:
  7.   fonction_a_la_con()
  8.   {
  9.     ...
  10.     m_dlgMachin.SetCallBackGestionEtat( SetEtatMachin );
  11.   }
  12.   CDialogMachin m_dlgMachin;
  13. }
  14. class CDialogMachin : public CDialog
  15. {
  16. ...
  17. public:
  18.   void SetCallBackGestionEtat(void pFonction(ETAT etat))
  19.   {
  20. m_pfGereEtat = pFonction;
  21.   }
  22. private:
  23.   void OnChangeEtatMachin(CDialogMachin::ETAT etat)
  24.   {
  25.     ...
  26.     if(m_pfGereEtat!=NULL)
  27.        m_pfGereEtat(mon_nouvel_etat);
  28.   };
  29. private:
  30.   void (* m_pfGereEtat) (ETAT etat);
  31. }


 
à la compilation, j'ai une erreur :

'SetCallBackGestionEtat' : cannot convert parameter 1 from 'void (enum CDialogMachin::ETAT)' to 'void (__cdecl *)(enum CDialogMachin::ETAT)'


Cette erreur pointe sur la ligne où je tente (comme un gorêt) de passer ma fonction en paramètre

Code :
  1. m_dlgMachin.SetCallBackGestionEtat( SetEtatMachin );


 
Bon... Je pleure :cry: Je ne sais pas comment faire :cry:


Message édité par Kalipok le 04-05-2004 à 14:50:53
Reply

Marsh Posté le 04-05-2004 à 11:41:36   

Reply

Marsh Posté le 04-05-2004 à 11:43:05    

le message st assez explicit eje pense :
 
pointeur sur membre != pointeur de fonction.
 
Regarde du coté de make_memptr ou passe ton membre en statique.

Reply

Marsh Posté le 04-05-2004 à 11:45:14    

Joel F a écrit :

le message st assez explicit eje pense :
 
pointeur sur membre != pointeur de fonction.
 
Regarde du coté de make_memptr ou passe ton membre en statique.


Ahem... Pardon ?

Reply

Marsh Posté le 04-05-2004 à 11:47:11    

Reply

Marsh Posté le 04-05-2004 à 11:53:27    

Merci :jap:  
Mais... Il n'existe aucun moyen simple et standard pour passer une fonction membre en paramètre d'une autre fonction ?
Les pointeurs de fonction sont forcément compliqués à utiliser ?  :heink:  
Merdum :o

Reply

Marsh Posté le 04-05-2004 à 12:14:57    

oh ya pas de destructeur virtuel [:dawa]
 
sinon les pointeurs de membres ça marche sans problème :o
 

Code :
  1. #include <iostream>
  2. struct Foo
  3. {
  4.   void foo()
  5.   {
  6.     std::cout << "void Foo::foo()\n";
  7.   }
  8.   void foo(int)
  9.   {
  10.     std::cout << "void Foo::foo(int)\n";
  11.   }
  12.   void foo() const
  13.   {
  14.     std::cout << "void Foo::foo() const\n";
  15.   }
  16.   static void bar()
  17.   {
  18.     std::cout << "static void Foo::bar()\n";
  19.   };
  20. };
  21. int main()
  22. {
  23.   Foo obj;
  24.   Foo *ptr(&obj);
  25.   typedef void (Foo::*Foofoov)();
  26.   typedef void (Foo::*Foofooi)(int);
  27.   typedef void (Foo::*Foofoovc)() const;
  28.   Foofoov a(&Foo::foo);
  29.   Foofooi b(&Foo::foo);
  30.   Foofoovc c(&Foo::foo);
  31.   (obj.*a)();
  32.   (obj.*b)(42);
  33.   (obj.*c)();
  34.   (ptr->*a)();
  35.   (ptr->*b)(42);
  36.   (ptr->*c)();
  37. }

Reply

Marsh Posté le 04-05-2004 à 12:46:23    

J'ai l'impression que j'ai surtout un problème de syntaxe [:meganne]
ça va me rendre fou cette histoire :pt1cable:
 
[Edit] Sinon, merci Taz, mais ton exemple ne m'aide pas... Mon problème est de passer une pointeur de fonction d'une classe à une autre, pas d'en créer un...


Message édité par Kalipok le 04-05-2004 à 13:26:43
Reply

Marsh Posté le 04-05-2004 à 13:34:23    

Kalipok a écrit :

Merci :jap:  
Mais... Il n'existe aucun moyen simple et standard pour passer une fonction membre en paramètre d'une autre fonction ?


 
ueh la STL c'est pas standard peut etre o_o  :heink:

Reply

Marsh Posté le 04-05-2004 à 13:38:12    

Joel F a écrit :

ueh la STL c'est pas standard peut etre o_o  :heink:


Ok mais je me dis qu'il doit bien y avoir moyen de faire sans... non ?
Pas moyen de passer un pointeur sur une fonction non statique en paramètre d'une fonction ?

Reply

Marsh Posté le 04-05-2004 à 13:40:58    

Kalipok a écrit :

Ok mais je me dis qu'il doit bien y avoir moyen de faire sans... non ?
Pas moyen de passer un pointeur sur une fonction non statique en paramètre d'une fonction ?

moi je parle pour rien comme d'habitude

Reply

Marsh Posté le 04-05-2004 à 13:40:58   

Reply

Marsh Posté le 04-05-2004 à 13:55:34    

Taz a écrit :

moi je parle pour rien comme d'habitude


 
he,  :sweat:

Reply

Marsh Posté le 04-05-2004 à 14:04:53    

Taz a écrit :

moi je parle pour rien comme d'habitude


Trop succint :o
désolé [:spamafote]
 
[Edit] Peut être ais je oublié de mentionner que ma classe CDialogMachin ne connait pas la classe CPageBidule... Pas de include, rien :o


Message édité par Kalipok le 04-05-2004 à 14:06:34
Reply

Marsh Posté le 04-05-2004 à 14:17:44    

Merci Joel et Taz, je vais utiliser une fonction statique...
Je regarderais quand même la solution de Joel plus tard pour voir...

Reply

Marsh Posté le 04-05-2004 à 14:22:41    

non mais c'est quoi ce foutoire : je file un exemple d'utilisation de pointeur de fonctions membres, en long et en large, et non, ça va pas ... c'est bon je retiens ton joli pseudo pour la prochaine fois,

Reply

Marsh Posté le 04-05-2004 à 14:29:15    

Taz a écrit :

non mais c'est quoi ce foutoire : je file un exemple d'utilisation de pointeur de fonctions membres, en long et en large, et non, ça va pas ... c'est bon je retiens ton joli pseudo pour la prochaine fois,


 
 :lol:

Reply

Marsh Posté le 04-05-2004 à 14:33:02    

Taz a écrit :

non mais c'est quoi ce foutoire : je file un exemple d'utilisation de pointeur de fonctions membres, en long et en large, et non, ça va pas ... c'est bon je retiens ton joli pseudo pour la prochaine fois,


Ben étant donné que tu as l'air du genre à te vexer quand on ne comprends pas tout de suite, tu ne vas pas me manquer [:spamafote]  :sleep:
 
[Edit] Je n'ai sûrement pas été clair... Pourtant Joel a bien répondu dans le sujet... lui...
 
[Edit2] J'ai édité le message initial, en espérant l'avoir clarifié un peu :sweat:


Message édité par Kalipok le 04-05-2004 à 14:53:08
Reply

Marsh Posté le 04-05-2004 à 20:26:52    

En parcourant qqs posts je constate que tu (taz) as qqs problèmes de communication... [:k@zouille]  
D'autant que tu es passé à côté de mon problème :heink:  
Heureusement que Joel est là pour me montrer que mon post était compréhensible mais que tu n'as tout simplement pas pris la peine de le lire [:tilleul]

Reply

Marsh Posté le 04-05-2004 à 22:31:21    

La solution 'static' contraint fortement la classe départ ce qui est dommage. L'exemple déjà donné - par tu sais qui - est pourtant clair.
 
Donc, il est possible d'appeler une fonction membre quelconque d'une classe numéro 1 quelconque à partir d'une classe numéro 2 sans utiliser 'static'.
 
La syntaxe est lourde et je ne sais pas si c'est parfaitement correct. Cela dit, j'ai bricoler la chose suivante et ca marche.
 

Code :
  1. #include<iostream>
  2. class Classe1
  3. {
  4. public:
  5. void FonctionAppelee() const
  6. {
  7. std::cout << "FonctionAppelee()" << std::endl;
  8. }
  9. };
  10. template< class T_CLASSE >
  11. class Classe2
  12. {
  13. public:
  14. void FonctionAppelante( T_CLASSE * C,
  15. void (T_CLASSE::*fonction)() const ) const
  16. {
  17. (C->*fonction)();
  18. }
  19. };
  20. int main()
  21. {
  22. Classe1 C1;
  23. Classe2<Classe1> C2;
  24. C2.FonctionAppelante( &C1, &Classe1::FonctionAppelee );
  25. //-- edit : retrait d'un cast
  26. }


Message édité par xterminhate le 04-05-2004 à 22:56:19

---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 04-05-2004 à 22:33:56    

Reply

Marsh Posté le 04-05-2004 à 22:36:01    

Euh... pour ma défense : pourquoi faire simple qd on peut faire compliqué. Désolé :)


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 04-05-2004 à 22:46:15    

Franchement, je lis courament l'anglais et je trouve les explications fournies par SGI pas claires du tout sur mem_fun.


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 04-05-2004 à 22:47:22    

(void (Classe1::*)() const) ... pourquoi tu castes ?  
 
fait un typedef et voilà ...

Reply

Marsh Posté le 04-05-2004 à 22:48:41    

Oui, le typedef s'impose mais j'ai eu la fleme de l'ecrire.


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 04-05-2004 à 22:53:50    


Peux-tu donner un exemple tout bète de mise en oeuvre de mem_fun, stp ?


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 04-05-2004 à 22:58:17    

Ne vous frittez pas, je suis une quiche, c'est tout :o
[:cupra]

Reply

Marsh Posté le 04-05-2004 à 23:02:39    

Pourtant, c'est calme là. :)


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 04-05-2004 à 23:10:02    

xterminhate a écrit :

Pourtant, c'est calme là. :)


Il suffirait que je dise que je ne vois pas comment appliquer vos exemples à mon cas pour déchaîner les passions :D

Reply

Marsh Posté le 04-05-2004 à 23:14:45    

T'inquiètes! Ils ne viendront quand même pas chez toi pour te tabasser. Enfin... ne fais pas trop de bétises, on sait jamais! :p


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 04-05-2004 à 23:22:40    

xterminhate a écrit :

T'inquiètes! Ils ne viendront quand même pas chez toi pour te tabasser. Enfin... ne fais pas trop de bétises, on sait jamais! :p


Je suis sérieux en plus [:cupra]
Dans mon cas, il y a deux classes uniquement, pas de main() en vue (VC++ MFC tout ça...)
 
Ma classe A instancie ma classe B et souhaite lui passer un pointeur sur une de ses fonctions (A::fonction(paramètres)) pour que lors des traitements réalisés dans B, un certain état de B déclenche une réaction de A.
 
Je ne peux pas faire de typedef void (A::*fonction(blabla)) dans B puisque B ne connait pas A.
 
Enfin bon... le static, c'est pas si mal  :whistle:
Sinon, j'ai toujours le B::GetParent() de base, mais bon...


Message édité par Kalipok le 04-05-2004 à 23:24:33
Reply

Marsh Posté le 04-05-2004 à 23:37:33    

Je ne peux pas faire de typedef void (A::*fonction(blabla)) dans B puisque B ne connait pas A.  
 
Ca veut dire quoi exactemet "ne connais pas" ? Tu peux faire un template si tu ne veux pas te lier à la classe A uniquement.


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 04-05-2004 à 23:58:01    

xterminhate a écrit :

Je ne peux pas faire de typedef void (A::*fonction(blabla)) dans B puisque B ne connait pas A.  
 
Ca veut dire quoi exactemet "ne connais pas" ? Tu peux faire un template si tu ne veux pas te lier à la classe A uniquement.


Par "ne connais pas", j'entends qu'il n'y a pas d'include du fichier définissant la classe A.
Pour le template : à quel niveau ? Transformer ma classe B (qui je le rappelle est une CDialog) ?
 
Bon... J'avoue que l'objectif est plus de faire un code simple et compréhensible rapidement plus que de faire du code optimisé  :whistle:, le static risque donc d'être retenu [:cupra]


Message édité par Kalipok le 05-05-2004 à 00:00:47
Reply

Marsh Posté le 05-05-2004 à 09:16:50    

Tu compiles qd même A et B en même temps, non ?


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 05-05-2004 à 09:18:53    

xterminhate a écrit :

Peux-tu donner un exemple tout bète de mise en oeuvre de mem_fun, stp ?


 
et dis donc, ta touche Scroll Down est cassée ?
 

Code :
  1. struct B {
  2.   virtual void print() = 0;
  3. };
  4. struct D1 : public B {
  5.   void print() { cout << "I'm a D1" << endl; }
  6. };
  7. struct D2 : public B {
  8.   void print() { cout << "I'm a D2" << endl; }
  9. };
  10. int main()
  11. {
  12.   vector<B*> V;
  13.   V.push_back(new D1);
  14.   V.push_back(new D2);
  15.   V.push_back(new D2);
  16.   V.push_back(new D1);
  17.   for_each(V.begin(), V.end(), mem_fun(&B::print));
  18. }

Reply

Marsh Posté le 05-05-2004 à 09:46:05    

Si, elle marche tres bien ma touche!
 
Mais, il s'agit de l'exemple donné partout. Je le connais par coeur :) Non, si tu as un autre exemple sans foreach, ca m'interesse toujours.
 
mem_fun(&B::print) correspond a l'appel du constructeur ?
mem_fun crée une fonction objet de telle manière que l'appel de son operateur en passant l'addresse d'un classe de type de base B execute la fonction print() ?


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 05-05-2004 à 10:35:30    

xterminhate a écrit :

Tu compiles qd même A et B en même temps, non ?


Ben... oui... fatalement
Sinon por mem_fun, il est clair que la page de sgi n'est pas franchement limpide... Encore moins si l'on souhaite passer des variables dans la fonction pointée :o

Reply

Marsh Posté le 05-05-2004 à 10:57:38    

xterminhate a écrit :


mem_fun(&B::print) correspond a l'appel du constructeur ?


 
rtfm :o
 

xterminhate a écrit :


mem_fun crée une fonction objet de telle manière que l'appel de son operateur en passant l'addresse d'un classe de type de base B execute la fonction print() ?


 
oui

Reply

Marsh Posté le 05-05-2004 à 11:30:36    

rtfm ... oui mais bon, a priori il a pas besoin de tout ça ...

Reply

Marsh Posté le 05-05-2004 à 13:33:47    

D'ailleurs... J'ai mis (en gros) mon code dans le premier message... Il aurait été aussi rapide de l'éditer pour mettre le code correct dedans...
En recoupant mon code et vos exemples, je serais certainement parvenu à qq chose, mais là... :'(

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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