Re: Casting for serializable struct (Was: Re: Casting always bad?)
Wu Yongwei wrote:
struct BaseMsgType {
enum MsgType { Type1, Type2, Type3 };
MsgType m_uMsgType;
size_t m_uLen;
BaseMsgType(MsgType uMsgType, size_t len)
: m_uMsgType(uMsgType), m_uLen(len) {}
}
struct MsgType1 {
// Some data members here
MsgType1() : BaseMsgType(Type1, sizeof(MsgType1)) ) {}
};
struct MsgType2 {
// Some data members here
MsgType2() : BaseMsgType(Type2, sizeof(MsgType2)) ) {}
};
When reading such data from network, file, or shared memory, casting
seems unavoidable.
Any better alternatives here?
Note: I realize that you are not necessarily espousing this type of
programming. I am speaking to those who do.
You're not going to like my answer, but I will give it anyway. ;)
*Don't* do that. :)
In a nutshell, the whole "Everything is an abstraction, long live the
abstraction!" thing has gone a little too far. Those "objects" are too
abstract. Look at them. There is nothing discernable about their
nature. Some might argue that this is what makes abstraction so
beautiful. I say not. I say that people who subscribed to this type
of "engineering" are simply deferring or eliminating thinking
altogether. The word 'struct' itself, implies form. An engineer
should seek to find the form. Finding the form is sometimes hard, but
it is what gives rigor to the final concoction. What is implied in the
above code is, "I don't know the form of the messages, so I will just
write my code in such a manner that it won't matter." In fact, it
matters very much. This "flexibility" is actually a disguised reversion
to ad-hoc, incremental, procedural programming. It's just that some
programmers can't see it, or they do see it, and know that it benefits
them.
So how would I do the equivalent? I would first stay in the land of
concrete as long as possible, eliminating the notion that objects are
so smart, they can brush their teeth and tie their own shoelaces while
invoking their virtual functions. I would utilize context. The
context is where the intelligence would lie. The objects themselves
would maintain their own state but little else. Polymorphism and
serialization never worked well together, and the trickery often
employed to 'force' them to be serializable usually introduces a
complexity that saps brain energy that might have better been applied
toward finding a form to obviate the polymorphism in the first place.
For those rare cases where polymorphism is simply unavoidable, I would
maintain a table that contains triplets of:
1. portable class name as a string
2. non-portable type id as string
3. function that can construct via serialization an object of that
specific class from a source with portable class name as one of its
arguments.
When the objects are serialized to the target, the portable class name
would be sent with it.
-Le Chaud Lapin-
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]