C ++非侵入式boost序列化boost :: smart_ptr

时间:2013-04-08 01:44:32

标签: c++ boost shared-ptr boost-serialization

我正在尝试序列化一个我无法使用 boost :: serialization 修改的自定义类,我需要将逻辑/计算代码与序列化部分区分开来。 它有一些我要序列化的受保护和私有字段,其中一些是其他类的 boost :: shared_ptr

类似的东西:

// 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类,只在其定义中添加了“友元类”:

class A_ser;
class A
{
   friend class A_ser;
   //...
};

并添加一个代理类来序列化它,它引用了A类的字段:

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

所以,当在A上调用序列化方法时,会改为使用A_ser。

当我尝试对B类执行相同操作时出现问题,因为在其反序列化中它尝试调用未定义的构造函数A():

  

boost / serialization / access.hpp:132:错误:没有匹配函数来调用'A :: A()'

如果我尝试将默认参数添加到A的构造函数中,它只会初始化一个全新的空类。

哦,我正在使用boost 1.53.0。

非常感谢提前。

编辑:解决方案(这很简单......)

只需修改* _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;
};

并添加

template< class Archive >
void load_construct_data(Archive & /*ar*/, A * t, unsigned /*v*/)
{
   ::new(t) A(0);
}

问题解决了(感谢Arun)!!

1 个答案:

答案 0 :(得分:2)

您可以使用serialize non-default-constructible objects with boost方法解决问题。 谷歌了解save_construct_data和load_construct_data用法示例。

另请查看Splitting serialize into Save/Load