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 :

[C++] Pointeur sur fonctions membres virtuelles


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 16
    Points : 13
    Points
    13
    Par défaut [C++] Pointeur sur fonctions membres virtuelles
    Bonjour à tous,

    Je vais essayer d'expliquer clairement mon problème. J'ai une classe de base Tool qui représente un outil sélectionné par l'utilisateur que je dérive en une classe ConcreteTool pour mon exemple. De la même façon, j'ai une classe Event (événement utilisateur) dérivée en MouseDownEvt par exemple auquel mon ConcreteTool réagit. L'idée c'est que chaque événement connait la fonction membre de ConcreteTool à appeller. Chaque Event possède donc un pointeur vers une fonction membre virtuelle de Tool. Voici l'allure de mes classes :

    Tool.h
    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
     
    class Tool
    {
     
    public:
        Tool(void);
        ~Tool(void);
     
        virtual void onLeftMouseDown(void* sender, EventArg* e) {} 
        virtual void onLeftMouseUp(void* sender, EventArg* e) {}
        virtual void onLeftMouseDrag(void* sender, EventArg *e) {}
        ...
    };
     
    class ConcreteTool
    {
     
    public:
     
        virtual void onLeftMouseDown(void* sender, EventArg* e) 
        {
             std::cout<<test<<std::endl;
        } 
         ...
    };
    Event.h
    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
     
    class EventArg;
    class Tool;
    typedef void (Tool::*toolFnPtr)(void*, EventArg*);
     
    class Event
    {
    protected :
     
        void* sender;
        EventArg* arg;
        toolFnPtr callback;
     
    public:
        Event(void);
        ~Event(void);
     
        inline void* getSender() const { return sender ; }
        inline toolFnPtr getCallback() const { return callback; }
        inline virtual EventArg* getArguments() { return arg; }
    };
    Pour créer un événement, je m'y prend comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    MouseDownEvt::MouseDownEvt(void *evtSender, const Vect2 &p, ModifierKey key) : Event()
    {
        sender = evtSender;
        arg = new MouseDownEvtArg(p, key);
        callback = &Tool::onLeftMouseDown;
    }
    Enfin, un gestionnaire traite l'événement ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void ToolSystem::treatEvent(Event *evt)
    {
        void* sender = evt->getSender();
        EventArg* arg = evt->getArguments();
        toolFnPtr fun = evt->getCallback();
        (currentTool->*fun)(sender, arg); // CRASH
        ...
    }
    Je compile avec le compilo de vs2005 et comme raison du crash, j'ai droit à un "Acces violation". En observant les adresses avec le débuggueur, j'ai remarque qu'il y avait des différences.

    Variable:---------------------Value:-----------------Type
    &Tool::onLeftMouseDown-----0x00411b90"U‹ììÌ"-------char *
    fun--------------------------0x00356818 ------------void (void *, EventArg *)*
    &IdleTool::onLeftMouseDown -0x00411a30"U‹ìjÿh+qA"--char *

    Ces adresses sont aussi différentes des adresses de la vtable de currentTool.

    Quelqu'un peut-il me dire où ça cloche et comment y remédier ? J'espère avoir été assez clair.
    Merci d'avance.

  2. #2
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 266
    Points : 6 688
    Points
    6 688
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    je n'ai pas tout compris, notamment la création d'unévénement (fonction MouseDownEvt::MouseDownEvt), mais si ça peut aider: lorsque j'ai besoin d'utiliser des pointeurs de fonctions, j'utilise boost::function, ce qui évite pas mal d'erreurs.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 16
    Points : 13
    Points
    13
    Par défaut
    En fait, j'ai trouvé comment le faire fonctionner, mais je ne saurais pas dire pourquoi celle-ci fonctionne alors que la première version non. Il suffit de modifier très légèrement le code, notamment de déplacer le typedef du pointeur sur fonction membre à l'intérieur de la classe Tool, et de le déclarer de la façon suivante là où on en a besoin.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Tool::toolFnPtr fun = evt->getCallback();
    Voilà. Merci r0d pour ta réponse.

  4. #4
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 266
    Points : 6 688
    Points
    6 688
    Billets dans le blog
    2
    Par défaut
    Merci à toi pour ton retour positif

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. pbm pointeurs sur fonction membre :)
    Par overbreak dans le forum C++
    Réponses: 8
    Dernier message: 15/02/2008, 16h14
  2. [POO] Pointeur sur fonction membre et héritage
    Par MrDuChnok dans le forum C++
    Réponses: 9
    Dernier message: 20/07/2006, 18h19
  3. Pointeur sur fonction membre avec parametre
    Par Glosialabolas dans le forum C++
    Réponses: 7
    Dernier message: 06/02/2006, 03h32
  4. Réponses: 10
    Dernier message: 03/02/2005, 14h09
  5. Réponses: 5
    Dernier message: 12/01/2005, 21h58

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