Re: Question on private virtual methods
On 18.07.2012 02:02, plegdfmds@gmail.com wrote:
Hi everyone,
"Content-Transfer-Encoding: quoted-printable"
^ Why are you doing that? The *ONLY* effect is to screw up things. It
was invented for passing mails across 7-bit hosts: there are no more
such hosts today.
I have a question on how to structure some private virtual methods.
No, you have an XY question.
You have a problem X, for which you have devised an idea of solution Y.
The idea Y is ungood in many respects, so you're asking about how to fix
it, instead of more reasonably asking about how to do X.
However, you're not the first to do that XY confusion thing for this
particular question.
Even the Boost guys did it.
MY problem is: I have some classes I need to serialize on a vector of bytes
to be transmitted (and then reconstructed on the other end). What I want
to do is having a class "Serializable" (inherited by all serializable
classes) that specifies the interface of the (de)serialization mechanism,
while the implementation is left to some private virtual methods that the
derived classes need to implement.
Deserialization cannot, IMHO, reasonably be done via virtual methods in
the class to be deserialized, because with deserialization you want to
pass the relevant information to *constructors*.
In other words, nearly all extant serialization/deserialization library
solutions for C++, including Boost serializations, are unreasonable:
they're at cross purposes with the C++ language design.
That said, once you choose this unreasonable almost-solution, which
requires you to create zombie objects that then are initialized via
deserialization, just go with the flow. You have then already dispensed
with the main C++ ideals, so there's NO POINT in desperately holding on
to some very much lesser design level C++ ideals such as private
overrides. That would be like unthinkingly defecating on the floor of a
restaurant (with other guests watching), and then desperately trying to
be polite when asking other guests at the restaurant for toilet paper.
Hey, politeness went down the drain, so to speak, with the defecation
action. It's just absurd to then cling to the lesser ideals!
For example, for a class A:
class Serializable
{
public:
Bytestream serialize();
void deserialize(Bytestream&);
private:
virtual Bytestream serializeStep1() = 0;
virtual void deserializeStep1(Bytestream&) = 0;
};
Bytestream Serializable::serialize() {
return serializeStep1();
}
void Serializable::deserialize(Bytestream&) {
deserializeStep1(Bytestream&);
}
class A: public Serializable
{
private:
virtual Bytestream serializeStep1();
virtual void deserializeStep1(Bytestream&);
};
and A implements serializeStep1 e deserializeStep1 depending on its internal members.
Now, my problem is: class A is itself inherited by classes B!, B2 etc. I'd like to
build a "cascaded serialization": in the serialization of B1, first A is serialized
and then the internals of B1 are serialized and appended to the Bytestream.
Well, as I understand it the Boost guys at one point seriously
considered using Johannes' infamous access of private methods, for this.
See his blog entry "Access to private members. That's easy!", at <url:
http://bloglitb.blogspot.no/2010/07/access-to-private-members-thats-easy.html>.
But don't do that: instead, make the methods protected. Remember, the
defecation has already happened, by the choice of in-class virtual
functions for deserialization, i.e. by not using constructors, and
having zombie objects around. More politeness after that is just absurd.
How to do this? The only thing I can think of is a cascade of
private methods like this:
Well, you could add non-private methods, but that's equally absurd.
Just go with the flow.
Or do it properly.
Cheers & hth.,
- Alf