I have real message classes eg
class Specific1Message {
//various functions to get different types of data
};
class Specific2Message {
//various functions to get different types of data
};
which I cannot change.
I am re-writing a software tool which encodes and decodes these messages. It decides which messages to decode/encode at runtime.
A load of specific messages get retrieved from a text file to be replayed to mimic a real system. The messages are temporarily stored in a std::list. To make the new/delete lifecycle more robust I have been asked to use smart pointers.
My first idea on the messages was to do something like this :-
class proto_msg : public ref_type {
public:
}
//ref_type is a smart pointer class
class Specific1msg : public proto_msg {
public:
Specific1Message m_msg; //instance of specific 1 message - composition
};
But I have functions in my tool which takes a proto_msg* as a parameter. So I was thinking that to get to the Specific1Message (for example) I would just do this:
int SpecificMessageHandler::EncodeMsg(proto_msg* msg, unsigned char* buffer, int size)
But then how to retrieve a Specific1Message? msg->GetMsg() – but how to define this method? What would it return?
I would need to define GetMsg() in the base class. But what is the return type? That is what I can’t fathom? Or maybe I need a rethink.
EDIT
Thank you for all the responses. I learnt about multiple dispatch amongst other things.
In the end I decided to do it like this :-
class realproto {
public:
const char* getName() const { return "realproto"; }
};
class real2ndproto {
public:
const char* get2Name() const { return "real2ndproto"; }
};
template<typename T>
class ProtoWrapper : public ref_type {
public:
ProtoWrapper(T* real) : m_msg(real) {}
~ProtoWrapper() { delete m_msg; } //cannot have smart ptr on real_proto - so do this way
T* getMsg() { return m_msg; }
private:
T* m_msg;
};
Then call like this
ref_ptr<ProtoWrapper <realproto> > msg2 = new ProtoWrapper<realproto>(new realproto);
realproto* pr1 = msg2->getMsg(); //if need underlying protocol
This should hopefully allow me to remove the void* s with the least code changes required.
The only options I can think of is template + double dispatching