I'm trying to serialize a custom class that I cannot modify using boost::serialization, and I need to keep the logic/computational code apart from the serialization part. It has some protected and private fields I've to serialize, and some of them are boost::shared_ptr of other classes.
Something like:
// computational classes
class A
{
public:
A(int a) : m_val(a) {}
private:
int m_val
};
class B
{
public:
B(a) : m_ptr(new A(a)) {}
private:
boost::shared_ptr< A > m_ptr;
};
A simple workaround I've found to serialize class A, only adding a "friend class" in its definition:
class A_ser;
class A
{
friend class A_ser;
//...
};
and adding a proxy class to serialize it, which has the reference to class A's fields:
class A_ser
{
public:
A_ser(A & a) : m_val(A.m_val) {}
template< class Archive >
void serialize(Archive & ar, const unsigned int version)
{
ar & m_val;
}
private:
int & m_val;
};
namespace boost {
namespace serialization {
template< class Archive >
void serialize(Archive & ar, A & a, const unsigned int version)
{
A_ser sa(a);
ar & sa;
}
} // namespace serialization
} // namespace boost
so, when the serialization method is called on A, A_ser's one is used instead.
Problems are occurring when I try to do the same with class B, since in its deserialization it tries to call the constructor A() wich is not defined:
boost/serialization/access.hpp:132: error: no matching function for call to 'A::A()'
and if I try putting a default argument to A's constructor, it just initialises a brand new, empty, class.
Oh, I'm using boost 1.53.0.
Many thanks in advance.
EDIT: solution (it was so simple..)
Just by modifying the *_ser references
class A_ser
{
public:
A_ser(A & a) : m_a(A) {}
template< class Archive >
void serialize(Archive & ar, const unsigned int version)
{
ar & m_a.m_val;
}
private:
A & m_a;
};
and adding
template< class Archive >
void load_construct_data(Archive & /*ar*/, A * t, unsigned /*v*/)
{
::new(t) A(0);
}
the problem was solved (thanks to Arun)!!
you can solve the problem using serialize non-default-constructible objects with boost approach. Google out for save_construct_data and load_construct_data usage examples.
Also have a look at Splitting serialize into Save/Load.