How would you serialize/deserialize this class using boost::serialization?
#include
struct Foo {
struct Bar {
std::vector
There is a section in the documentation that describes how to (de)serialize classes with non-default constructors. See here.
Basically, you must implement two functions called save_construct_data
and load_construct_data
in the namespace boost::serialization
to write out and read in the data used to construct instances of your class. You can then call a non-default constructor of Foo
from the load_construct_data
function with the parameters necessary to reconstruct a Foo
object.
Here is a working example based on your updated code:
Note that I've used shared_ptr
's to clarify that the data
member serialized by Foo and Bar are referencing the same thing.
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct Foo {
struct Bar {
boost::shared_ptr< std::vector > data; // Must point to Foo::data
Bar( boost::shared_ptr< std::vector > d ) : data(d) { }
template
void serialize(Archive & ar, const unsigned int version)
{
// ** note that this is empty **
}
};
boost::shared_ptr< std::vector > data;
std::vector elements;
Foo() : data( new std::vector() ) {
std::cerr << "Running default constructor" << std::endl;
data->push_back(1);
data->push_back(2);
data->push_back(3);
data->push_back(4);
data->push_back(5);
elements.push_back( Bar( data ) );
elements.push_back( Bar( data ) );
elements.push_back( Bar( data ) );
}
template
void serialize(Archive & ar, const unsigned int version)
{
// ** note that this is empty **
}
Foo(
boost::shared_ptr< std::vector > const & data_,
std::vector const & elements_ ) : data( data_ ), elements( elements_ )
{
std::cout << "cheap construction" << std::endl;
}
};
namespace boost { namespace serialization {
template
inline void save_construct_data(
Archive & ar, const Foo * foo, const unsigned int file_version
){
ar << foo->data << foo->elements;
}
template
inline void load_construct_data(
Archive & ar, Foo * foo, const unsigned int file_version
){
boost::shared_ptr< std::vector > data;
std::vector elements;
ar >> data >> elements;
::new(foo)Foo(data, elements);
}
template
inline void save_construct_data(
Archive & ar, const Foo::Bar * bar, const unsigned int file_version
){
ar << bar->data;
}
template
inline void load_construct_data(
Archive & ar, Foo::Bar * bar, const unsigned int file_version
){
boost::shared_ptr< std::vector > data;
ar >> data;
::new(bar)Foo::Bar(data);
}
}}
int main()
{
std::stringstream ss;
{
boost::scoped_ptr< Foo > foo( new Foo() );
std::cout << "size before serialization is: " << foo->data->size() << std::endl;
boost::archive::text_oarchive oa(ss);
oa << foo;
}
{
boost::scoped_ptr< Foo > foo;
boost::archive::text_iarchive is(ss);
is >> foo;
std::cout << "size after deserialization is: " << foo->data->size() << std::endl;
}
return 0;
}