Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Question on private virtual methods

Reply
Thread Tools

Question on private virtual methods

 
 
plegdfmds@gmail.com
Guest
Posts: n/a
 
      07-18-2012
Hi everyone,
I have a question on how to structure some private virtual methods.

MY problem is: I have some classes I need to serialize on a vector of bytesto 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 derivedclasses need to implement. 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, firstA is serialized and then the internals of B1 are serialized and appended to the Bytestream.

How to do this? The only thing I can think of is a cascade of private methods like this:


class A: public Serializable
{
private:
virtual Bytestream serializeStep1();
virtual Bytestream serializeStep2() = 0;
virtual void deserializeStep1(Bytestream&);
virtual void deserializeStep2(Bytestream&) = 0;
};
Bytestream A::serialize() {
return serializeStep1() + serializeStep2(); // il '+' concatena
}
void A::deserialize(Bytestream&) {
deserializeStep1(Bytestream&);
deserializeStep2(Bytestream&);
}


class B1: public A
{
private:
virtual Bytestream serializeStep2();
virtual void deserializeStep2(Bytestream&);
}


but it doesn't look good, because now I need to structure A differently depending whether it's inherited or not.

How to do this?

Thx!
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      07-18-2012
On 7/17/2012 8:02 PM, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> I have a question on how to structure some private virtual methods.
>
> 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. 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&);
> }


I don't think it's warranted. Or, your class is misnamed, and should be
named 'SerializableInStep1'.

>
>
> 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.
>


Looks like B1's implementation should just call the base class'
*protected* member.

> How to do this? The only thing I can think of is a cascade of
> private

methods like this:
>
>
> class A: public Serializable
> {
> private:
> virtual Bytestream serializeStep1();
> virtual Bytestream serializeStep2() = 0;
> virtual void deserializeStep1(Bytestream&);
> virtual void deserializeStep2(Bytestream&) = 0;
> };
> Bytestream A::serialize() {
> return serializeStep1() + serializeStep2(); // il '+' concatena
> }
> void A::deserialize(Bytestream&) {
> deserializeStep1(Bytestream&);
> deserializeStep2(Bytestream&);
> }
>
>
> class B1: public A
> {
> private:
> virtual Bytestream serializeStep2();
> virtual void deserializeStep2(Bytestream&);
> }
>
>
> but it doesn't look good, because now I need to structure A
> differently depending whether it's inherited or not.


A couple of comments. Generally, design is out of scope in a language
newsgroup, unless it's language-specific, and here it's not. Second,
your 'Serializable' class imposes an unnecessary limitation on the
derived classes, IMO, to implement the 'step1' interface. What for?
Just force the derived classes to implement 'serialize' and 'de-'
methods, and let them decide how to perform [de]serialization. Third,
if you want sequential serialization, perhaps a policy is a better way.
See 'Modern C++ Design' by Alexandrescu.

Perhaps if you elaborated a bit more on *why* step1 and step2 are the
model requirements, it would be a bit more obvious... I know, it's not
much of help, but without knowing the underlying model, it's kind of
hard to recommend any particular solution or even evaluate the presented
solution. Sorry.

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
 
 
 
plegdfmds@gmail.com
Guest
Posts: n/a
 
      07-18-2012
> I don't think it's warranted. Or, your class is misnamed, and should be
> named 'SerializableInStep1'.


What do you mean?



> Looks like B1's implementation should just call the base class'
> *protected* member.


I could do that, yes. But I wanted to see if there's a way to call "forward" from the base to the derived, and not the other way.


> Second,
> your 'Serializable' class imposes an unnecessary limitation on the
> derived classes, IMO, to implement the 'step1' interface. What for?
> Just force the derived classes to implement 'serialize' and 'de-'
> methods, and let them decide how to perform [de]serialization.


To separate the interface from the implementation. There's some more stuff in Serializable::serialize() that I didn't show because it's not relevant here; it looks more like:

Bytestream Serializable::serialize() {
[steps common to all serializable classes]
serializeStep1();
[more steps common to all serializable classes]
}

so the Serializable class defines the inetrface and the common steps, and the derived classes just implement what they need to implement.
 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      07-18-2012
On 18.07.2012 02:02, (E-Mail Removed) 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
 
Reply With Quote
 
Nick Keighley
Guest
Posts: n/a
 
      07-18-2012
On Jul 18, 7:59*am, "Alf P. Steinbach" <alf.p.steinbach
(E-Mail Removed)> wrote:
> On 18.07.2012 02:02, (E-Mail Removed) 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.


could you expand on this? I tried to implement serialization using
constructors
and didn't quite get it to gell.

Would you use a constructor like this
Serializable (istream&)

The touble is until you've read at least some of the object you don't
know its type. I ended up with some sort of factory that cloned
registered objects.

The C++ FAQ has a serialization section
http://www.parashift.com/c++-faq-lit...alization.html

what the hell happened to the format!?


<snip>


> > *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-e...>.
> 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.
>

 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      07-18-2012
On 18.07.2012 19:49, Leigh Johnston wrote:
>
> struct bar : foo
> {
> bar() {}
> bar(const i_stream& p) : foo() { deserialize(p); }
> virtual void deserialize(const i_stream& p) { foo::deserialize(p);
> p >> c; p >> d; }
> virtual void serialize(i_stream& p) { foo::serialize(p); p << c; p
> << d; }
> int c;
> std::string d;
> };
>
> Works quite well.


uhm, perhaps the stream is a little bit too immutable?


cheers,

- Alf


 
Reply With Quote
 
woodbrian77@gmail.com
Guest
Posts: n/a
 
      07-19-2012
On Wednesday, July 18, 2012 1:49:01 PM UTC-4, Leigh Johnston wrote:
>
> I use something like the following to handle serialization:
>
> struct i_stream
> {
> // functions to encode/decode types to/from a stream ...
> };
>
> struct i_serializable
> {
> virtual void deserialize(const i_stream&amp; p) = 0;
> virtual void serialize(i_stream&amp; p) = 0;
> };
>
> struct foo : i_serializable
> {
> foo() {}
> foo(const i_stream&amp; p) { deserialize(p); }
> virtual void deserialize(const i_stream&amp; p) { p &gt;&gt; a; p &gt;&gt; b; }
> virtual void serialize(i_stream&amp; p) { p &lt;&lt; a; p &lt;&lt; b; }
> int a;
> std::string b;
> };
>
> struct bar : foo
> {
> bar() {}
> bar(const i_stream&amp; p) : foo() { deserialize(p); }
> virtual void deserialize(const i_stream&amp; p) { foo::deserialize(p); p &gt;&gt;
> c; p &gt;&gt; d; }
> virtual void serialize(i_stream&amp; p) { foo::serialize(p); p &lt;&lt; c; p &lt;&lt; d; }
> int c;
> std::string d;
> };
>
> Works quite well.
>



The C++ Middleware Writer automates the writing of marshalling
functions. For example, a user adds function prototypes to
his class like this:

class cmw_account_info {
::cmw::marshalling_integer accountnumber;
::std::string password;

cmw_account_info ()
{}

template <class R>
explicit cmw_account_info (::cmw::ReceiveBuffer<R>& buf);

void CalculateMarshallingSize (::cmw::Counter& cntr) const;
void MarshalMemberData (::cmw::SendBuffer& buf) const;
void Marshal (::cmw::SendBuffer& buf, bool = false) const
{
MarshalMemberData(buf);
}
};


The C++ Middleware Writer maintains the implementations
of the function prototypes for you.


Shalom,
Brian
Ebenezer Enterprises
http://webEbenezer.net
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Private methods not so private? Frank Meyer Ruby 14 08-02-2007 07:29 PM
Why is define_method private? Plus,what's the point of private methods? Daniel Finnie Ruby 3 12-16-2006 10:09 PM
Private methods called from public methods Robert Javascript 16 05-06-2006 11:32 PM
Should 'public virtual' always become 'private virtual'? & using private inheritance qazmlp C++ 19 02-04-2004 12:37 AM
Re: Templates and friends and template methods with private methods. Buster Copley C++ 5 07-07-2003 12:50 AM



Advertisments