Question

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)!!

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top