derived class and serialization

Hello.. I use serialization to communicate betwen client and server.. Base and derived class for serialization (communication): class base { }; class derived : base { }; What would be the 'good' way to export/import serialized data? Can I do this with smart pointers? Is this okay: WRITING: derived dc(4, 5, "some data"); std::ostringstream archive_stream; boost::archive::text_oarchive archive(archive_stream); archive & dc; //send archive_stream.str() over network RECIVING: should I use base class pointer when deserializing? or can I do it with base class reference? For instance: base *bc; bc & in_data; ///////// I'm little confused about reciving data.. I tried using base class reference for deserializing derived class, but it doesnt work and it seems unlogical to do it this way.. I would be really glad if someone could explain.. Thanks a lot

This is not hard - but it can be tricky. To use many of the features of the serialization library you can almost just slap it together, fix up the errors and be amazed that it works. Not true with serialization through a base class pointer. a) read the documenation and examples on this point. b) if you want to do this with smart pointers, look at the smart pointer demo/example c) remember to make your base class polymorphic - make at least one function virtual. Serialization through a base class pointer can be very useful and powerful techniqued. Good Luck Robert Ramey Aljaz wrote:
Hello.. I use serialization to communicate betwen client and server..
Base and derived class for serialization (communication):
class base { }; class derived : base { };
What would be the 'good' way to export/import serialized data? Can I do this with smart pointers?
Is this okay:
WRITING: derived dc(4, 5, "some data"); std::ostringstream archive_stream; boost::archive::text_oarchive archive(archive_stream); archive & dc; //send archive_stream.str() over network
RECIVING: should I use base class pointer when deserializing? or can I do it with base class reference?
For instance: base *bc; bc & in_data;
///////// I'm little confused about reciving data.. I tried using base class reference for deserializing derived class, but it doesnt work and it seems unlogical to do it this way.. I would be really glad if someone could explain..
Thanks a lot

Hey
I took a look at smart pointer example..
However, I need different approach in the following code:
spa = boost::shared_ptr<A>(new B);
spa1 = spa;
display(spa, spa1);
// serialize it
{
std::ofstream ofs(filename.c_str());
boost::archive::text_oarchive oa(ofs);
oa.register_type(static_cast(NULL));
oa << spa;
oa << spa1;
}
Do I have to register_type this way? Can I use BOOST_EXPORT .. instead?
When I want to deserialize data, the derived class will be unknown, so I
have to deserialize data with base class shared pointer..
This will then contain information - type of derived class, and then I will
cast it to derived class..
How could I do this?
Thank you very much
"Robert Ramey"
This is not hard - but it can be tricky. To use many of the features of the serialization library you can almost just slap it together, fix up the errors and be amazed that it works. Not true with serialization through a base class pointer.
a) read the documenation and examples on this point. b) if you want to do this with smart pointers, look at the smart pointer demo/example c) remember to make your base class polymorphic - make at least one function virtual.
Serialization through a base class pointer can be very useful and powerful techniqued.
Good Luck
Robert Ramey

Aljaz wrote:
Hey
I took a look at smart pointer example.. However, I need different approach in the following code:
spa = boost::shared_ptr<A>(new B); spa1 = spa; display(spa, spa1); // serialize it { std::ofstream ofs(filename.c_str()); boost::archive::text_oarchive oa(ofs); oa.register_type(static_cast(NULL)); oa << spa; oa << spa1; }
Do I have to register_type this way? Can I use BOOST_EXPORT .. instead?
Yes
When I want to deserialize data, the derived class will be unknown, so I have to deserialize data with base class shared pointer..
This will then contain information - type of derived class, and then I will cast it to derived class..
You may not have to do this. And you may not want to. The typical use case for using an abstract base class is to have all the functions in the derived class declared private and be called only through the the virtual function table in the abstract base class. The separates the interface defined in the abstract base class defined from the specific implementation in the derived class.
How could I do this?
a) You can embed a function in the base class like who_am_i() which returns an indictator of what kind of class it "really" is. b) you can use a function from the extended_type_info family of the serialization library to do something similar Neither of these are recommend as far as I'm concerned. The best is to make all the functions you want to call virtual and call them through the base class. This topic is addressed in Scott Meyers "Effective C++" Another effect is that you can add more derived classes without even recompiling the code you're already using. There is a demo in the serialization library which illustrates this.
Thank you very much
you're welcome Robert Ramey

Do I have to register_type this way? Can I use BOOST_EXPORT .. instead?
Yes
I tried doing BOOST_CLASS_EXPORT(B), but program crashed when I wanted to deserialize data..
When I want to deserialize data, the derived class will be unknown, so I have to deserialize data with base class shared pointer..
This will then contain information - type of derived class, and then I will cast it to derived class..
You may not have to do this. And you may not want to. The typical use case for using an abstract base class is to have all the functions in the derived class declared private and be called only through the the virtual function table in the abstract base class. The separates the interface defined in the abstract base class defined from the specific implementation in the derived class.
How could I do this?
a) You can embed a function in the base class like who_am_i() which returns an indictator of what kind of class it "really" is. b) you can use a function from the extended_type_info family of the serialization library to do something similar
Neither of these are recommend as far as I'm concerned. The best is to make all the functions you want to call virtual and call them through the base class. This topic is addressed in Scott Meyers "Effective C++"
Another effect is that you can add more derived classes without even recompiling the code you're already using. There is a demo in the serialization library which illustrates this.
Why I want to ID derived class through base class? Because derived class will contain a lot of data, that wont be in base class. If I had only functions in derived class, I would make them virtual and call from base class.. I already made function get_type() that returns type of derived class.. But I still have no idea if I have smart pointer to base class, how do I get smart pointer do derived class from it? Is there any example using extended_type_info family to do something similar? Thank you!

Aljaz wrote:
Do I have to register_type this way? Can I use BOOST_EXPORT .. instead?
Yes
I tried doing BOOST_CLASS_EXPORT(B), but program crashed when I wanted to deserialize data..
I don't know what to say here. Its been tested, demo'ed and documented. .
Why I want to ID derived class through base class? Because derived class will contain a lot of data, that wont be in base class.
This topic is addressed in Scott Meyers "Effective C++"
I already made function get_type() that returns type of derived class.. But I still have no idea if I have smart pointer to base class, how do I get smart pointer do derived class from it?
I would expect one could do a dynamic cast of the shared ptr - but this is really a question for someone else.
Is there any example using extended_type_info family to do something similar?
I looked at the documentation for extended_type_info which requires the implementation of get_derived_type_info for each kind of extended_type_info object created. However its not document for general usage. I suppose that this is because that I didn't think it would be used for anything other than an implementation detail. Subsequently however, I used it as part of boost/serialization/detail/shared_ptr_helper. You can look into that file to see how this was done. Robert Ramey
participants (2)
-
Aljaz
-
Robert Ramey