IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Les callback et les classes


Sujet :

C++

  1. #1
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 629
    Points : 30 692
    Points
    30 692
    Par défaut Les callback et les classes
    Salut,

    J'ai (peut etre très mal) cherché tant sur le net que sur le forum, mais je j'ai pas trouvé réellement la réponse que je cherche...Je me permet donc de vous la poser ici:

    Je cherche à comprendre le mécanisme d'implémentation du callback d'une méthode de classe.

    Par exemple, une classe toute simple du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class MaClass
    {
        private:
    //some members
       public:
       void Mafonct(int a, int b);
    }
    Pour ce que j'en ai compris, il faut commencer par déclarer une variable qui contienne un pointeur de fonction.

    En travaillant proprement, on utiliserait le typedef sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    typedef void(*ptr2int) (int, int);
    ptr2int MonPtrFonction;
    (les noms étant surtout choisis pour la compréhension)
    Le deuxième travail est de créer une fonction qui appelle la fonction pointée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void CallBack2int(ptr2int ptr)
    {
        ptr();
    }
    (déjà, là, j'ai un doute sur les arguments à passer à CallBack2int )

    Voilà, en gros, ce que j'ai compris (si j'ai fait une erreur quelque part, merci de me le signaler )

    Les questions qui tuent: En allant du plus simple au plus compliqué:

    Q1- Comment implémenter les choses pour qu'un appel du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    main
    {
    //...
         CallBack2int(MonPtrFonction);
    }
    appelle la méthode Mafonct de ma classe ?
    Q2- Comment implémenter CallBack2int et MonPtrFonction pour qu'ils soient respectivement méthode et membre de MaClasse (qu'un appel à CallBack2int se fasse sous la forme de MonObjet->CallBack2int() ou MonObjet.CallBack2int () selon les circonstance)?

    Y a-t-il des points auxquels il faut etre attentif? (membres et/ou méthodes statiques, par exemple)

    Q3- CallBack2int peut il etre méthode virtuelle pure dans un but polymorphique?

    Je vous remercie d'avance

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Points : 307
    Points
    307
    Par défaut
    Une fonction membre a besoin d'une information en plus des paramètres : l'instance d'un objet sur laquelle elle va s'appliquer. Pour faire ce que tu veux, tu vas devoir utiliser quelque chose comme boost::bind.

    Pour ta troisième question, je n'a jamais testé avec boost::bind, mais intuitivement ça devrait marcher.

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Pour les pointeurs de fonction ete les classes, je dois avouer que je n'ai jamais utilisé de pointeur sur fonctions membres non-statiques.

    Mais je peux faire un exemple sur des fonctions membres statiques:
    Considérons une fonction callback qui prend en paramètre un pointeur et deux entiers. L'un des entiers sera un paramètre utilisateur, l'autre sera généré par la fonction qui appelle la callback.
    Code C/C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef void (*ProcPtrDeuxInt)(void *pVoid, int nUser, int nIntern);
     
    void AppelerCallback(ProcPtrDeuxInt callBack, void *pVoid, int nUser)
    {
        int nIntern = QuelqueChose();
     
        callBack(pVoid, nUser, nIntern);
    }

    Maintenant, si on veut bosser avec des objets, on peut faire ainsi, sans modifier le type ni la fonction appelante:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class CUneClasse
    {
    public:
        //On va la faire virtual en plus, si on veut
        virtual void VFaireQuelqueChose(int nUser, int nIntern);
     
        static void SLaFonctionPtrDeuxInt(void *pVoid, int nUser, int nIntern);
    };
     
     
    void CUneClasse::VFaireQuelqueChose(int nUser, int nIntern)
    {
        /* On fait un truc */
    }
     
    //[static]
    void CUneClasse::SLaFonctionPtrDeuxInt(void *pVoid, int nUser, int nIntern)
    {
        CUneClasse *pObj = static_cast< CUneClasse * >(pVoid);
        pObj->VFaireQuelqueChose(nUser, nIntern);
    }
    On voit ici que la fonction statique appelle la fonction de l'objet, qui peut être virtuelle.

    Et pour invoquer le tout, on fait un truc comme ça:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main(void)
    {
        int nUnNombre = 42;
        CUneClasse unObj;
     
        AppelerCallback(CUneClasse::SLaFonctionPtrDeuxInt, &unObj, nUnNombre);
        return 0;
    }

    Note: J'ai fait tout ça de tête, sans testé. Mais c'est l'esprit, si ça ne marche pas je corrigerai.

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 629
    Points : 30 692
    Points
    30 692
    Par défaut
    De fait, ton code fonctionne correctement.

    Je vais voir à l'adapter à un exemple plus compliqué, et, si j'ai d'autres questions, je reviendrai sur le sujet

  5. #5
    Nouveau membre du Club
    Inscrit en
    Juin 2005
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 36
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par koala01
    Q3- CallBack2int peut il etre méthode virtuelle pure dans un but polymorphique?
    Que quelqu'un me contredise si j'ai faux, mais de mon expérience, ça ne fonctionne pas... Peut-être qu'il existe des implémentations dont je n'ai cure qui vont marcher avec le polymorphisme, mais la mienne en tout cas ne fonctionne pas... (en même temps, contourner le problème côté code client ne coùte presque rien)

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Le mieux pour les callback c'est d'utiliser boost.function

  7. #7
    Membre émérite
    Avatar de Ti-R
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2003
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 683
    Points : 2 568
    Points
    2 568
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    #include <cstdlib>
    #include <iostream>
     
    using namespace std;
     
    class A
    {
    	public:
    	A(){}
     
    	virtual void functA()
    	{
    			cout << "echoA\n";
    	}		
     
    	virtual void functAP()=0;
     
    };
     
    class B:public A
    {
    	public:
    	B(){}
     
    	void functA()
    	{
    			cout << "echoB\n";
    	}	
     
    	void functAP()
    	{
    			cout << "echoB Pure\n";
    	}	
    };
     
    int main(int argc, char *argv[])
    {
    	void (A::*pt_funct)();
     
    	pt_funct = &A::functA;
    	B b;
    	(b.*pt_funct)();
     
    	A *a = new B();
     
    	(a->*pt_funct)();
    	delete a;
     
    // Pur
    	pt_funct = &A::functAP;
     
    	B b_p;
    	(b_p.*pt_funct)();
     
    	A *a_p = new B();
     
    	(a_p->*pt_funct)();
    	delete a_p;
     
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    Je viens de tester rapidement, et pas de problème, compilé sous DevCpp

  8. #8
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 629
    Points : 30 692
    Points
    30 692
    Par défaut
    Merci...

    Donc, on pourrait, selon les réponses obtenues, résumer ca sous la forme de

    -Un callback dans un objet doit etre static, donc, 1fonction appelée-->1 callback

    -Callback et polymorphisme: oui si le callback en lui-meme est externe à tout objet

    (au passage: merci, vos codes m'ont permis de trouver les erreurs que je commettais )

    Citation Envoyé par loufoque
    Le mieux pour les callback c'est d'utiliser boost.function
    Je n'en doute pas, mais le but de ma question était surtout de me permettre de "fixer" dans mon esprit le mécanisme du callback...

    A titre "pédagogique", il est donc mieux de "s'amuser" à en créer un de toutes pièces

    Je n'ai strictement rien contre les bibliotheques existantes, bien au contraire, mais je travaille généralement dans l'optique d' "apprendre à me débrouiller par moi meme avant de trouver les bibliotheques qui le font pour moi"...

  9. #9
    Membre émérite
    Avatar de Ti-R
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2003
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 683
    Points : 2 568
    Points
    2 568
    Par défaut
    Citation Envoyé par koala01
    Merci...

    Donc, on pourrait, selon les réponses obtenues, résumer ca sous la forme de

    -Un callback dans un objet doit etre static, donc, 1fonction appelée-->1 callback

    -Callback et polymorphisme: oui si le callback en lui-meme est externe à tout objet

    (au passage: merci, vos codes m'ont permis de trouver les erreurs que je commettais )
    J'ai peu être mal compris ce que tu viens de dire, mais tu as regardé mon code ?

    Tu peux faire l'appel d'une fonction statique à un objet, mais tu peux aussi faire l'appel d'une fonction non statique.

    Citation Envoyé par koala01
    oui si le callback en lui-meme est externe à tout objet
    Tu peux appeler une fonction de n'importe où... statique ou non...

  10. #10
    Membre habitué
    Avatar de superspag
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    153
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 153
    Points : 186
    Points
    186
    Par défaut
    J'ai posté un exemple qui implementation un appel à une callback qui est une fonction membre d'une classe, en utilisant les librairies proposées par boost :

    http://www.developpez.net/forums/sho...d.php?t=195169

    Si ça peut aider...

Discussions similaires

  1. afficher toutes les méthodes et les variables d'une classe
    Par riyad25h dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 07/07/2010, 10h22
  2. les methodes et les associations entre les classes
    Par zin_rbt dans le forum Diagrammes de Classes
    Réponses: 1
    Dernier message: 24/05/2010, 14h41
  3. Réponses: 2
    Dernier message: 29/05/2007, 22h48
  4. [VB6]Enumérer les attributs et les méthodes d'une classe
    Par HPJ dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 04/05/2004, 18h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo