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 :

[template] problème de passage de paramètres


Sujet :

C++

  1. #1
    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 [résolu][template] problème de passage de paramètres
    Je suis entrain de tenter de faire un mécanisme d'évènements. Le but est de pouvoir attacher des fonctions membres de n'importe quels objets qui sont appelées lorsque les évènements se déclenchent.

    La première classe permet d'appeler la fonction membre en question, via le pointeur sur l'objet concerné, elle dérive d'une interface afin de faire disparaître le paramètre template relatif au type de cet objet extérieur dans la seconde classe
    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
     
    	template< typename Ret, typename Args >
    	class SubscriberInterface
    	{
    	public:
    		virtual Ret operator()( Args args ) = 0;
    	};
     
    	template< class T, typename Ret, typename Args >
    	class Subscriber : public SubscriberInterface< Ret, Args >
    	{
    	public:
    		typedef Ret( T::*ObjectMethod )( Args );
    		Subscriber( ObjectMethod f, T* t )
    			: mpT( t ), mpF( f ) {};
    		Ret operator()( Args args )
    		{
    			return( mpT->*mpF )( args );
    		}
    	private:
    		T*				mpT;
    		ObjectMethod	mpF;
    	};
    La seconde classe, dont dérive l'objet emetteur d'évènements :
    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
     
    	template< typename Ret, typename Args >
    	class Subscribed
    	{
    	public:
    		template< class T >
    		void SubscribeEvent( ULONG ulEvent,
    		Ret( T::*f )( Args ), T* t )
    		{
    			mmapSubscribers[ new Subscriber< T, Ret, Args >( f, t ) ] = ulEvent;
    		}
     
    		void UnSubscribeEvent( ULONG ulEvent )
    		{
    			for( SubscriberMap::iterator itSubscribers = mmapSubscribers.begin();
    				itSubscribers != mmapSubscribers.end(); )
    			{
    				if( itSubscribers->second == ulEvent )
    				{
    					SubscriberInterface< Ret, Args >* psubscriber(
    						itSubscribers->first );
    					itSubscribers =
    						mmapSubscribers.erase( itSubscribers );
    					delete psubscriber;
    				}
    				else
    				{
    					++itSubscribers;
    				}
    			}
    		}
     
    		void FireEvent( ULONG ulEvent, Args& args )
    		{
    			for( std::map< SubscriberInterface<Ret,Args>*,ULONG >::iterator
    				itSubscribers = mmapSubscribers.begin();
    				itSubscribers != mmapSubscribers.end(); ++itSubscribers )
    			{
    				if( itSubscribers->second == ulEvent )
    				{
    					( *itSubscribers->first )( args );
    				}
    			}
    		}
     
    	private:
    		std::map< SubscriberInterface<Ret,Args>*,ULONG > mmapSubscribers;
    	};
    Dans la pratique, si le pointeur de la fonction et l'instance lors de l'appel à SubscribeEvent sont bons, à l'intérieur ils sont à 0 (et pas du même type d'après le débugger). Au final, la méthode censée être appelé lors de l'évènement ne l'est jamais, quelque chose est appelé pourtant, mais le code n'est pas visible. Ca ne plante jamais...

    Voilà j'ai un peu écumé le net, il semblerait que je n'ai pas fait d'erreurs de conception, mais je me trompe sans doute, donc si quelqu'un pouvait m'éclairer un coup, j'y vois rien du tout

    Merci.

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Salut

    Tout fonctionne très bien chez moi (VC++ 7.1). Voici le code que j'ai ajouté au tien afin de faire les tests :

    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
    struct Test : public Subscribed<bool, int>
    {
     
    };
     
    struct EventHandler
    {
        bool OnEvent1(int x) {cout << "OnEvent1 -- arg : " << x << " -- this = " << this << endl; return true;}
        bool OnEvent2(int x) {cout << "OnEvent2 -- arg : " << x << " -- this = " << this << endl; return true;}
        bool OnEvent3(int x) {cout << "OnEvent3 -- arg : " << x << " -- this = " << this << endl; return true;}
    };
     
     
    int main()
    {
        Test t;
        EventHandler e;
     
        cout << "&e = " << &e << endl;
     
        t.SubscribeEvent(1, &EventHandler::OnEvent1, &e);
        t.SubscribeEvent(2, &EventHandler::OnEvent2, &e);
        t.SubscribeEvent(3, &EventHandler::OnEvent3, &e);
     
        int p1 = 15, p2 = 24, p3 = -6;
        t.FireEvent(1, p1);
        t.FireEvent(3, p2);
        t.FireEvent(2, p3);
     
        return 0;
    }
    Sortie :

    &e = 0012FEAC
    OnEvent1 -- arg : 15 -- this = 0012FEAC
    OnEvent3 -- arg : 24 -- this = 0012FEAC
    OnEvent2 -- arg : -6 -- this = 0012FEAC
    Rien à voir avec ton problème : ton std::map me semble être utilisé à contre emploi (tu ne fais que du parcours / recherche linéaire). Pourquoi pas un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::multimap<ULONG, SubscriberInterface<Ret,Args>*>
    En supposant qu'un évènement peut être dispatché à plusieurs gestionnaires (dans le cas contraire c'est encore plus facile, tu peux utiliser std::map).

    Avec ça, UnsubscribeEvent et FireEvent se font en une ligne, si j'ai bien toute ma tête à 1h du mat'.

  3. #3
    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
    alors effectivement, ça marche très bien Merci de ta réponse ! J'avoue honteusement ne pas avoir pensé à faire une sortie dans la console pour vérifier...
    En fait je me fiais aveuglément au débugger, parce que pour lui, les méthode du EventHandler ne sont jamais appelées...

    Y a-t-il quelque chose à configurer pour qu'on puisse tracer ce code ?

    [edit]

    Après quelques nouveaux tests, le debugger parvient maintenant à parfaitement tracer le code appelé, ça venait sans doute du fait que, flemard que je suis, j'avais déclarer et défini la classe handler directement dans le cpp. Je ne pensais pas que ça pouvait avoir un impact, autant pour moi il semblerait que je me soit simplement inventé des problèmes qui n'existaient pas

    Toutefois, si quelqu'un a quoi que ce soit à rajouter ...

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 29/09/2006, 10h18
  2. Réponses: 19
    Dernier message: 09/06/2006, 10h03
  3. Problème de passage de paramètres à une procedure
    Par momo62 dans le forum x86 16-bits
    Réponses: 2
    Dernier message: 22/12/2005, 15h22
  4. Réponses: 9
    Dernier message: 13/05/2005, 03h13
  5. problème de passage de paramêtre sous mozilla
    Par mat10000 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 27/09/2004, 10h48

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