When implementing a MessageFactory class to instatiate Message objects I used something like:
class MessageFactory
{
public:
static Message *create(in
This is a modified version that uses a MessageFactory singleton and a std::map to store constructors. It works great so far but comments are welcome.
I am still trying to find a way to avoid creating constructors for each message class. I know is possible because the original library can do it. Unfortunately I only have the header files so no idea on the implementation details.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <map>
class Message
{
protected:
Message() {};
public:
virtual ~Message() { }
int getMessageType() const { return m_type; }
virtual void say() = 0;
protected:
uint16_t m_type;
};
template<int TYPE, typename IMPL>
class MessageTmpl: public Message
{
enum { _MESSAGE_ID = TYPE };
public:
static Message* Create() { return new IMPL(); }
static const uint16_t MESSAGE_ID; // for registration
static void Enable() { volatile uint16_t x = MESSAGE_ID; }
protected:
MessageTmpl() { m_type = MESSAGE_ID; } //use parameter to instanciate template
};
class MessageFactory
{
public:
typedef Message* (*t_pfFactory)();
static MessageFactory *getInstance()
{
static MessageFactory fact;
return &fact;
}
uint16_t Register(uint16_t msgid, t_pfFactory factoryMethod)
{
printf("Registering constructor for msg id %d\n", msgid);
m_List[msgid] = factoryMethod;
return msgid;
}
Message *Create(uint16_t msgid)
{
return m_List[msgid]();
}
std::map<uint16_t, t_pfFactory> m_List;
private:
MessageFactory() {};
MessageFactory(MessageFactory const&) {};
MessageFactory& operator=(MessageFactory const&);
~MessageFactory() {};
};
//std::map<uint16_t, t_pfFactory> MessageFactory::m_List;
template <int TYPE, typename IMPL>
const uint16_t MessageTmpl<TYPE, IMPL>::MESSAGE_ID = MessageFactory::getInstance()->Register(
MessageTmpl<TYPE, IMPL >::_MESSAGE_ID, &MessageTmpl<TYPE, IMPL >::Create);
class PingMessage: public MessageTmpl < 10, PingMessage >
{
public:
PingMessage() {}
virtual void say() { printf("Ping\n"); }
};
class PongMessage: public MessageTmpl < 11, PongMessage >
{
public:
PongMessage() {}
virtual void say() { printf("Pong\n"); }
};
int main(int argc, char **argv)
{
Message *msg1;
Message *msg2;
msg1 = MessageFactory::getInstance()->Create(10);
msg1->say();
msg2 = MessageFactory::getInstance()->Create(11);
msg2->say();
delete msg1;
delete msg2;
return 0;
}