Base class MessageHandler
has derived classes. They would like to pass messages to each other. Messages could be of different classes, but can be made to share a base class. How can each MessageHandler
avoid downcasting a received message? Is it somehow possible to do something that has the effect of template-parametrizing the virtual receiveMessage
function on MessageHandler?
Essentially, I'm trying to replace the following code with something that does not downcast, and is hopefully a compile-time thing:
// ...
virtual void MessageHandler::receiveMessage(Message &msg) = 0;
// ...
// to receive a message
void DerivedMessageHandler::receiveMessage(Message& msg)
{
switch (msg.MsgType()) // enum
{
case Message::MessageType::A:
MessageA& = dynamic_cast<MessageA&>(msg);
break;
case Message::MessageType::B:
MessageB& = dynamic_cast<MessageB&>(msg);
break;
default:
// don't process unknown messages
break;
}
}
// to send a message
list<MessageHandler> mhList;
// populate list
for (MessageHandler& mh : mhList)
{
mh.receiveMessage(msg);
}
I know I can't do this, but something like
template <typename M>
void MessageHandler::receiveMessage(M& msg) {}
And have each DerivedMessageHandler
specialize on M
? What would be a design pattern that cleanly lets each handler work on their supported message objects?