The documentation contains a section that describes how to (de) serialize classes with non-default constructors. See here .
Basically, you should implement two functions called save_construct_data
and load_construct_data
in the boost::serialization
namespace to write and read data used to instantiate your class. Then you can call the non-default Foo
constructor from the load_construct_data
function with the parameters needed to restore the Foo
object.
Here is an example based on the updated code:
Note that I used shared_ptr
to make it clear that the data
member serialized by Foo and Bar refers to the same thing.
#include <vector> #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/serialization/vector.hpp> #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/scoped_ptr.hpp> #include <boost/shared_ptr.hpp> #include <iostream> #include <sstream> struct Foo { struct Bar { boost::shared_ptr< std::vector<int> > data; // Must point to Foo::data Bar( boost::shared_ptr< std::vector<int> > d ) : data(d) { } template<class Archive> void serialize(Archive & ar, const unsigned int version) { // ** note that this is empty ** } }; boost::shared_ptr< std::vector<int> > data; std::vector<Bar> elements; Foo() : data( new std::vector<int>() ) { 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<class Archive> void serialize(Archive & ar, const unsigned int version) { // ** note that this is empty ** } Foo( boost::shared_ptr< std::vector<int> > const & data_, std::vector<Bar> const & elements_ ) : data( data_ ), elements( elements_ ) { std::cout << "cheap construction" << std::endl; } }; namespace boost { namespace serialization { template<class Archive> inline void save_construct_data( Archive & ar, const Foo * foo, const unsigned int file_version ){ ar << foo->data << foo->elements; } template<class Archive> inline void load_construct_data( Archive & ar, Foo * foo, const unsigned int file_version ){ boost::shared_ptr< std::vector<int> > data; std::vector<Foo::Bar> elements; ar >> data >> elements; ::new(foo)Foo(data, elements); } template<class Archive> inline void save_construct_data( Archive & ar, const Foo::Bar * bar, const unsigned int file_version ){ ar << bar->data; } template<class Archive> inline void load_construct_data( Archive & ar, Foo::Bar * bar, const unsigned int file_version ){ boost::shared_ptr< std::vector<int> > 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; }
source share