Hierarchie de message et de target
Le
amerio
Bonjour,
Je cherche a implémenter un système de message/target supportant héritage.
Dans le principe : on a une hiérarchie de Message, et une hiérarchie de Target acceptant
certains Message.
class Message { } // classe de base
class MessageSpecial : public Message { }
class MessageSpecialExt : public MessageSpecial { }
La classe de base des Target doit ressembler à ca :
class Target
{
Target();
virtual ~Target();
virtual bool OnMessage(Message& msg); // le point de reception public
protected:
virtual bool HandleMessage(Message& msg); // traitement du msg de base
}
Ce dont j'ai besoin :
class TargetSpecial : public Target
{
TargetSpecial();
virtual ~TargetSpecial();
protected:
virtual bool HandleMessageSpecial(MessageSpecial& msg);
}
A noter que je *veux* éviter d'avoir HandleMessageSpecial(Message& msg)
(pour éviter un cast a chaque fois, et c'est ça qui est dur)
J'ai vu l'exemple de Meyers dans More Effective C++, mais il est inapplicable pour moi :
- ça oblige a faire un cast (et je veux éviter) : HandleMessageSpecial(Message& msg)
- l'utilisation d'une map ne permet pas de gérer une hiérarchie de message (si j'ajoute
une nouveau message mais pas de handler associé, il sera ignorer et non traité, car non
trouvé dans le map)
J'ai perdu ma journée la dessus, alors toute idée est bienvenue.
Je cherche a implémenter un système de message/target supportant héritage.
Dans le principe : on a une hiérarchie de Message, et une hiérarchie de Target acceptant
certains Message.
class Message { } // classe de base
class MessageSpecial : public Message { }
class MessageSpecialExt : public MessageSpecial { }
La classe de base des Target doit ressembler à ca :
class Target
{
Target();
virtual ~Target();
virtual bool OnMessage(Message& msg); // le point de reception public
protected:
virtual bool HandleMessage(Message& msg); // traitement du msg de base
}
Ce dont j'ai besoin :
class TargetSpecial : public Target
{
TargetSpecial();
virtual ~TargetSpecial();
protected:
virtual bool HandleMessageSpecial(MessageSpecial& msg);
}
A noter que je *veux* éviter d'avoir HandleMessageSpecial(Message& msg)
(pour éviter un cast a chaque fois, et c'est ça qui est dur)
J'ai vu l'exemple de Meyers dans More Effective C++, mais il est inapplicable pour moi :
- ça oblige a faire un cast (et je veux éviter) : HandleMessageSpecial(Message& msg)
- l'utilisation d'une map ne permet pas de gérer une hiérarchie de message (si j'ajoute
une nouveau message mais pas de handler associé, il sera ignorer et non traité, car non
trouvé dans le map)
J'ai perdu ma journée la dessus, alors toute idée est bienvenue.

Poser une question


class Message
{
public:
virtual bool notify( Target * the_target ) { return
the_target->HandleMessage( *this ); } // *this est de type Message
};
class MessagePasSpecial : public Message
{
public:
// on ne redéfinit pas notify si on veut que HandleMessage( Message& ) gère
le message
};
class MessageSpecial : public Message
{
public:
bool notify( Target * the_target ) { return the_target->HandleMessage(
*this ); } // *this est de type MessageSpecial
};
class Target
{
public:
virtual bool HandleMessage( Message& );
};
class TargetSpecial : public Target
{
public:
virtual bool HandleMessage( MessageSpecial& );
};
Ensuite, pour gérer un message :
TargetSpecial ts;
Message * msg = GetNextMessage();
msg->notify( &ts );
Si msg pointe vers un MessageSpecial, notify devrait appeler
TargetSpecial::HandleMessage( MessageSpecial& ). Si il pointe vers un
Message ou MessagePasSpecial, notify appelle TargetSpecial::HandleMessage(
Message& )...
J'ai pas testé, et en plus il est tard. Si je suis à coté de la plaque, fais
des recherches sur double dispatch (ou pattern visitor), puisqu'il me semble
que c'est celà que tu veux. Note qu'en même temps, c'est ce dont parle
Meyers à ce qu'il me semble aussi...
Demain, il y fera plus clair :)
Chris
Sans attendre demain, je vois que mon code est à coté de la plaque...
Je ré-essaie demain (à priori, il faut une hiérarchie supplémentaire si on
veut pas de casts)..
Chris
template <class Msg> class TargetT: virtual public Target
{
virtual bool HandleMessage(Message& msg)
{
return HandleMessageSpecial (dynamic_cast<Msg&>(msg));
};
virtual bool HandleMessageSpecial (Msg& msg);
};
class TargetSpecial : public TargetT<MessageSpecial>
{
bool HandleMessageSpecial (MessageSpecial& msg);
};
--
;-)
Mais ça se complique si on veut qu'un Target gère plusieurs types différents
de messages. Je crois que c'est ce que veut faire Amerio.
Borland et Microsoft définissaient des tas de macros pour arriver à celà...
Chris
class TargetVraimentSpecial : public TargetT<AutreMessageSpecial>,
public TargetSpecial
{
bool HandleMessageSpecial (AutreMessageSpecial& msg);
bool HandleMessageSpecial (MessageSpecial& msg);
};
Un peu lourd à écrire il est vrai...