pointeur de fonction membre d'une classe

pointeur de fonction membre d'une classe - C++ - Programmation

Marsh Posté le 12-06-2004 à 18:55:48    

Pour situer je ne suis pas top du tout en C++, pour ne pas dur nul ...
Alors j'ai besoin de déclarer un pointeur de fonction sur une fonction membre d'une classe, et je n'y arrive pas ...

Code :
  1. class CCompressor : public IAudioPlugin
  2. {
  3. public:
  4. CCompressor();
  5. virtual ~CCompressor();
  6. void        DoAudioProcessing();
  7. ...
  8. };


autre fichier

Code :
  1. extern class CCompressor   *pCompressor;
  2. void (*pf)(void) = pCompressor->DoAudioProcessing;


 
\Compressor\Misc.cpp(43): error C2440: 'initialisation' : impossible de convertir de 'overloaded-function' en 'void (__cdecl *)(void)'
 
c'est juste pour simplifier que j'ai pris cet example, car ça n'a aucun intérêt dans ce cas.

Reply

Marsh Posté le 12-06-2004 à 18:55:48   

Reply

Marsh Posté le 12-06-2004 à 18:58:12    

 void (*pf)(void)
 
déjà le (void) il sert à rien
 
ensuite, ceci ne marche qu'avec les fonctions ou les fonctions membres statiques
 
encore une fois, je recolle l'exemple de base
 

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 12-06-2004 à 19:02:26    

Merci Maître !  :jap:

Reply

Marsh Posté le 13-06-2004 à 16:39:47    

Bon, ça fonctionne pour cet example, mais là c'est une autre paire de manche ...

Code :
  1. class CCompressor
  2. {
  3.     public:
  4. DLGPROC   CompressorProc( HWND hDlg, UINT uMsg, UINT wParam, LONG lParam);
  5. DLGPROC   FxProc( HWND hDlg, UINT uMsg, UINT wParam, LONG lParam);
  6. DLGPROC   (CCompressor::*pfDlg)( HWND hDlg, UINT uMsg, UINT wParam, LONG lParam);
  7. ...
  8. };


 
dans une fonction membre de la classe j'initialise le pointeur :

Code :
  1. pfDlg = &CCompressor::CompressorProc;


Et là où ça semble coincer c'est que dois utiliser ce truc dans une fonction membre statique :

Code :
  1. // From MSDN to use windows proc into a class
  2. /* ------------------------------------------------------------------------- */
  3. DLGPROC CCompressor::bdd_setupProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  4. /* ------------------------------------------------------------------------- */
  5. {
  6.     CCompressor    *p;
  7. ...
  8.     // and call its message proc method
  9.     if ( p != (CCompressor *)NULL) {
  10.         return( (p->*pfDlg)( hDlg, uMsg, wParam, lParam));
  11.     } else {
  12.         return( FALSE);
  13.     }
  14. }


là y a ces erreurs, alors que si j'appele directement la fonction c'est OK.
 
Misc.cpp(181): error C2568: '->*' : impossible de résoudre la surcharge de fonction
Misc.cpp(181): error C2597: référence non conforme à un membre non static 'CCompressor::pfDlg'


Message édité par cricri_ le 13-06-2004 à 16:41:06
Reply

Marsh Posté le 13-06-2004 à 17:04:32    

tu fais chier avec ton code et ses windoseries vomitives .... maintenant ton pfDlgffdlùmhglùmjfdqlhjslkmhjsfdlkmhl c'est un membre d'instance, il va pas se matérialiser comme ça ... un bon point pour le message à la con de VC à 400km de la plaque (p->*(p->pfDlggflmgqjrfpogheqrgokhvqdrykothzorenb-yzot))( hDlg, uMsg, wParam, lParam)
 
 
une dernière
 
p != (CCompressor *)NULL   tu crois faire quoi là ?


Message édité par Taz le 13-06-2004 à 17:26:34
Reply

Marsh Posté le 13-06-2004 à 17:20:40    

vi, s'pas grave ... je me débrouillerai autrement ...  :pfff:

Reply

Marsh Posté le 13-06-2004 à 17:25:51    

de quoi ? je viens de" te donner la solution !

Reply

Marsh Posté le 13-06-2004 à 17:35:05    

ben pfDlg est matérialisé à partir du moment où un objet de la clase compressor existe, et que ce pointeut a été initialisé précédemment : pfDlg = &CCompressor::CompressorProc;
non ? qu'est-ce que j'ai mal fait ?
a part les windowseries ...

Reply

Marsh Posté le 13-06-2004 à 17:37:36    

dans la définition d'une fonction membre
 
pfDlg = &CCompressor::CompressorProc;
 
tu sous-entends this->
 
 
 
en dehors, y a plus de this-> qui tienne, il faut bien que tu rattaches ton membre à une instannce !

Reply

Marsh Posté le 13-06-2004 à 17:44:54    

ok, c'est plus clair pour moi, le pb c'est que c'est dans une fonction statique, donc là c'est p qui devrait me rattacher le pointeur à l'instance, enfin c'est tout ce que j'ai il me semble.

Reply

Marsh Posté le 13-06-2004 à 17:44:54   

Reply

Marsh Posté le 13-06-2004 à 17:46:35    

Taz a écrit :

void (*pf)(void)
 
déjà le (void) il sert à rien
 
ensuite, ceci ne marche qu'avec les fonctions ou les fonctions membres statiques

:o

Reply

Marsh Posté le 13-06-2004 à 18:07:54    

c'est bien mon cas ça, ce pointeur de fonction est utilisé dans une fonction membre statique, par contre son initialisation est effectuée dans une fonction membre.
Bon, je sens que ça ne va pas être possible mon histoire ..

Reply

Marsh Posté le 13-06-2004 à 18:09:54    

et comment veut tu que ça soit possible ?

Reply

Marsh Posté le 13-06-2004 à 18:13:54    

ce que je ne comprends pas c'est pourquoi ce n'est pas possible, car si je remplace le pointeur de fonction par la fonction ça marche.
Mais c'est clair qu'il doit y avoir un truc qui m'échappe.

Reply

Marsh Posté le 13-06-2004 à 18:15:25    

ben une fonction membre statique n'est rattachée à aucune instance. une fonction membre non statique l'est. ce sont 2 choses bien différentes .| t'as pas l'air de comprendre ces concepts


Message édité par Taz le 13-06-2004 à 18:15:59
Reply

Marsh Posté le 13-06-2004 à 18:22:31    

sissi j'ai bien compris, mais puisque dans cette fonction statique je récupère un pointeur sur cette instance, p en l'occurence, je ne pige pas pourquoi je peux faire :

Code :
  1. (p->CompressorProc)( hDlg, uMsg, wParam, lParam);


 
mais pas :

Code :
  1. (p->*pDlg)( hDlg, uMsg, wParam, lParam);


alors que pDlg a été déclaré précédemment dans une fonction membre :

Code :
  1. pfDlg = &CCompressor::CompressorProc;


[edit correction]


Message édité par cricri_ le 13-06-2004 à 18:23:10
Reply

Marsh Posté le 13-06-2004 à 18:24:23    

parce que. et si t'appelles une fonction statique avec un instance, t'as un gros problème :o

Reply

Marsh Posté le 13-06-2004 à 18:26:51    

Taz a écrit :

tu fais chier avec ton code et ses windoseries vomitives .... maintenant ton pfDlgffdlùmhglùmjfdqlhjslkmhjsfdlkmhl c'est un membre d'instance, il va pas se matérialiser comme ça ... un bon point pour le message à la con de VC à 400km de la plaque (p->*(p->pfDlggflmgqjrfpogheqrgokhvqdrykothzorenb-yzot))( hDlg, uMsg, wParam, lParam)
 
 
une dernière
 
p != (CCompressor *)NULL   tu crois faire quoi là ?


 
 
 
Bjarn Stroustrup a écrit : "J'ai appris beaucoup de choses en écrivant ce livre car celui qui connaitrait tout du C++ n'est pas encore né" (où plus précisemment, il dit "n'existe pas encore" )  
 


---------------
"Je suis si intelligent que mon cerveau est mon deuxième organe favori".
Reply

Marsh Posté le 13-06-2004 à 18:32:13    

et ?

Reply

Marsh Posté le 13-06-2004 à 18:36:31    

je n'ai pas le choix, c'est une windowserie ... les fonctions appelées à la création d'une boîte de dialogue ne peuvent pas être des fonctions membres, donc il faut appeler une fonction statique ou non membre, dans mon cas c'est une fonction statique, on passe l'instance (this) en paramètre que l'on récupère dans la fonction statique afin d'appeler la fonction membre ...
Je suis bien d'accord que c'est du pure windaube, mais bon, j'essaye de faire avec ...
Et donc je ne vois pas bien comment faire autrement, hormis déclarer un enum qui me permettra de choisir la fonction à appeler, mais je trouve ça assez crade ...


Message édité par cricri_ le 13-06-2004 à 18:37:29
Reply

Marsh Posté le 13-06-2004 à 18:45:46    

ben dans les fonctions callback non template, on mets souvent un argument genre *userdata, comme ça ton cb est appelé avec et là tu peux travailler. sinon, t'es foutu

Reply

Marsh Posté le 13-06-2004 à 18:53:55    

vi, y a ça, mais il est déjà utilisé pour passer l'instance (this).
.. mais tu viens de me donner une idée, je vais essayer de passer le pointeur de fonction plutôt que l'instance ;)

Reply

Marsh Posté le 13-06-2004 à 18:58:42    

et ben si tu passe l'instances, il est ou le problème : rien ne t'empeche de faire une fonction statique avec en paramètre une instance :o

Reply

Marsh Posté le 13-06-2004 à 19:07:40    

Mais c'est bien ce qui était fait, pourtant j'avais tjs cette erreur !

Reply

Marsh Posté le 13-06-2004 à 19:14:54    

non, c'est pas ce qui était fait

Reply

Marsh Posté le 13-06-2004 à 19:26:38    

Ah ? bon, je récapitule alors, voilà ce que j'ai fait :

Code :
  1. class CCompressor : public IAudioPlugin
  2. {
  3. public:
  4.     static DLGPROC  bdd_setupProc( HWND hwndDlg, UINT uMsg,
  5.                                    WPARAM wParam, LPARAM lParam);
  6.     DLGPROC         PluginAudioProc( HWND hDlg, UINT uMsg,
  7.                UINT wParam, LONG lParam);
  8. DLGPROC   CompressorProc( HWND hDlg, UINT uMsg, UINT wParam, LONG lParam);
  9. DLGPROC   FxProc( HWND hDlg, UINT uMsg, UINT wParam, LONG lParam);
  10. DLGPROC   (CCompressor::*pfDlg)( HWND hDlg, UINT uMsg, UINT wParam, LONG lParam);
  11. ....


 
pfDlg est initialisé dans une fonction membre :

Code :
  1. pfDlg = &CCompressor::CompressorProc;


 
et la fonction statique en entier :

Code :
  1. // From MSDN to use windows proc into a class
  2. /* ------------------------------------------------------------------------- */
  3. DLGPROC CCompressor::bdd_setupProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  4. /* ------------------------------------------------------------------------- */
  5. {
  6.     CCompressor *p;
  7.     switch ( uMsg) {
  8.     case WM_INITDIALOG :
  9.         // This message is how we identify the dialog object.
  10.         // get a pointer to the class object.
  11.         p = (CCompressor *)lParam;
  12.         // set its USERDATA word to point to the class object
  13.         SetWindowLong( hDlg, GWL_USERDATA, (long)p);
  14.         break;
  15.     default :
  16.         // get a pointer to the class object
  17.         p = (CCompressor *)GetWindowLong( hDlg, GWL_USERDATA);
  18.         break;
  19.     }
  20.    
  21.     // and call its message proc method
  22.     if ( p != (CCompressor *)NULL) {
  23.         return((p->*pfDlg)( hDlg, uMsg, wParam, lParam));
  24.     } else {
  25.         return( FALSE);
  26.     }
  27. }


et dans cette fonction statique si je remplace p->*pfDlg par p->CompressorProc ça fonctionne.
 
rappel des erreurs :
Misc.cpp(181): error C2568: '->*' : impossible de résoudre la surcharge de fonction
Misc.cpp(181): error C2597: référence non conforme à un membre non static 'CCompressor::pfDlg'


Message édité par cricri_ le 13-06-2004 à 19:27:42
Reply

Marsh Posté le 13-06-2004 à 19:47:48    

et tu persistes et signes ... débrouilles toi tout seul

Reply

Marsh Posté le 13-06-2004 à 19:54:43    

???
S'il n'y a pas de solution suffit de me le dire, sinon j'aimerai bien la connaitre


Message édité par cricri_ le 13-06-2004 à 19:57:03
Reply

Marsh Posté le 13-06-2004 à 19:58:49    

j'aimerais juste que tu arrêtes de balancer tes windowseries
 
class CCompressor : public IAudioPlugin
  {
    public:
        static DLGPROC  bdd_setupProc( HWND hwndDlg, UINT uMsg,
                                       WPARAM wParam, LPARAM lParam);
        DLGPROC         PluginAudioProc( HWND hDlg, UINT uMsg,
                    UINT wParam, LONG lParam);
     DLGPROC   CompressorProc( HWND hDlg, UINT uMsg, UINT wParam, LONG lParam);
     DLGPROC   FxProc( HWND hDlg, UINT uMsg, UINT wParam, LONG lParam);
     DLGPROC   (CCompressor::*pfDlg)( HWND hDlg, UINT uMsg, UINT wParam, LONG lParam);  
 
je vois ça, je quitte direct, j'ai pas envie de lire ce genre de ramassi

Reply

Marsh Posté le 13-06-2004 à 20:00:07    

surtout que tu t'entêtes à balancer tes immondices sans prendre en compte mes réflexions : le problème est le même qu'au début

Reply

Marsh Posté le 13-06-2004 à 20:02:27    

ok, malheureusement mon pb est lié à ce contexte ...
Bon bah tant pis.

Reply

Marsh Posté le 13-06-2004 à 20:04:11    

tant pis pour toi, je t'ai pourtant filé la solution

Reply

Marsh Posté le 13-06-2004 à 20:33:31    


 
et que tu devrais relire la phrase plusieurs fois, tous les matins.  


---------------
"Je suis si intelligent que mon cerveau est mon deuxième organe favori".
Reply

Marsh Posté le 13-06-2004 à 21:06:35    

strobo a écrit :

et que tu devrais relire la phrase plusieurs fois, tous les matins.

c'est parce que je te fais pas un rapport tous les jours que j'apprends pas. je suis arrivé sur le forum il n'y a pas si longtemps. et j'apprends tous les jours, pas sur le forum évidemment. je vois pas pourquoi tu essaies de m'approprier ce genre de pensée

Reply

Marsh Posté le 13-06-2004 à 21:17:46    

Taz a écrit :

tant pis pour toi, je t'ai pourtant filé la solution


possible, maintenant j'ai annoncé la couleur dès le début, suis pas top en C++, maintenant j'ai certainement raté qqchose mais je ne vois pas.

Reply

Marsh Posté le 13-06-2004 à 21:21:46    

je te dis que ton sdlhgqsdlkhgsdlkghklqghqslkghlfqghklqgqdlghlqdghi c'est un membre, alors écris le comme un membre

Reply

Marsh Posté le 13-06-2004 à 21:46:23    

T'es vraiment le pire des chi*nt, mais t'es génial !!!  :love:  
 :jap: merci

Reply

Marsh Posté le 13-06-2004 à 21:47:34    

Taz a écrit :

maintenant ton pfDlgffdlùmhglùmjfdqlhjslkmhjsfdlkmhl c'est un membre d'instance, il va pas se matérialiser comme ça ... un bon point pour le message à la con de VC à 400km de la plaque (p->*(p->pfDlggflmgqjrfpogheqrgokhvqdrykothzorenb-yzot))( hDlg, uMsg, wParam, lParam)

j'aime pas qu'on me fasse répéter

Reply

Marsh Posté le 13-06-2004 à 21:55:03    

vi, maintenant que j'ai compris je réalise que tu m'avais donné la solution, maintenant à coup de hjdsqmiuiazeadjkldjlkzdlz, pas facile non plus ... pire que des windauberies ... ;)
mais j'avais pas mal cherché sur l'histoire, et je n'ai rien trouvé sur les pointeurs de fonctions membre d'une classe, si tu as qqs URLs suis preneur, même si là je crois avoir compris.
Encore merci .  :jap:

Reply

Marsh Posté le 13-06-2004 à 22:16:07    

ben flfhdfhqfhflmdhfsqdhmlfqsdfsq c'est aussi compréhensible de prime abord que pfdl

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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