Re: Common code between unrelated classes
On Jan 18, 11:44 pm, forums...@hotmail.com wrote:
In a Client Server setup execution flow is often akin to:
a) Read Client Data -> b) Process -> c) Write Server Data
d) Read Server Data -> e) Update -> f) Write Client Data
On the Client side, I'm faced with two classes.
class Base_Message { virtual ~Base_Message() {} };
class CMsg1 : public Base_Message {}; //CMsg: from Client
class SMsg1 : public Base_Message {}; //SMsg: to Client
class Handle_Incoming : public Base_Handler {
CMsg1 Client_Msg ;
public:
void Process () { /* work */ }};
class Handle_Outgoing : public Base_Handler {
SMsg1 Server_Msg ;
public:
void Update ( /*...*/ ) { /*update Server_Msg* pre f) above */ }
};
My question becomes: How do I make SMsg1 available for both
Handle_Incoming and Handle_Outgoing classes when a relationship among
them doesn't exist?
Lots of options, including:
In class Handle_Incoming...
void process_and_load(Handle_Outgoing&);
...and in class Handle_Outgoing...
friend class Handle_Incoming;
OR
In class Handle_Incoming...
void process_and_load(SMsg1&);
...in class Handle_Outgoing...
void process(Handle_Incoming& i) { i.process_and_load
(Server_Msg); }
The common base class, interest in run-time polymorphism, and trailing
'1' all imply you're only listing one from families of input and
output classes, though I'm not convinced the options were understood
and the choices deliberate enough for this deduction to be
meaningful...? You haven't indicated why you'd use the same base
class for inputs and outputs - that seems undesirably imprecise if not
actually needed.
While in some ways it's good to keep them separate, you could instead
combine message data and processing, adding a factory method like...
virtual Base_Message* prepare_reply() const;
....into your CMsg1 class, doing away with Handle_Incoming and
Handle_Outgoing, but perhaps the Handle classes allude to an event-
driven callback context...?
I'm really not sure why you're trying to achieve what you've asked to,
so can't recommend any of these.
It's important to realise that the complexities above are due to
having avoiding the simplest implementation: two message classes just
having basic member functions to get/set their data, while a single
external function does something like:
while (CMsg1 input = comms_link.receive())
{
SMsg1 output(input);
comms_link.update(output);
}
Adding polymorphism (assuming separate Client_Base_Message and
Server_Base_Message for clarity):
while (Client_Base_Message* p_client_msg =
Client_Base_Message::factory(comms_link))
{
if (Server_Base_Message* p_server_msg = p_client_msg-
prepare_reply())
{
comms_link.update(p_server_msg);
delete p_server_msg;
}
delete p_client_msg;
}
Add smart pointers for exception safety....
In an asynchronous event-driven environment, there's a use for your
Handle_Incoming - which would normally coordinate the server message
preparation and client updates. I can't see a need for
Handle_Outgoing... you don't normally react to your own outputs.
Cheers,
Tony
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]