【问题标题】:Serialization tree structure using boost::serialization使用 boost::serialization 的序列化树结构
【发布时间】:2010-07-23 07:01:47
【问题描述】:

我必须在我的程序中序列化libkdtree++,树结构简单描述如下:

struct _Node_base {
  _Node_base * _M_parent, *_M_left, * _M_right;

  template<Archive>
  serialize(Archive &ar, const unsigned int version) {
    ar & _M_left & _M_right;
  }
}

template<typename V>
struct _Node : public _Node_base {
  typedef V value_type;
  value_type value;
  template<Archive>
  serialize(Archive &ar, const unsigned int version) {
    ar.register_type(static_cast<_Node*>(NULL));
    ar & boost::serialization::base_object<_Node_base>(*this);
    ar & value;
  }
}

struct Tree {
  _Node * root;
  template<Archive>
  serialize(Archive &ar, const unsigned int version) {
    ar & root;
  }
}

此程序报告“流错误”。 但是从“serailized 文件”中,它缺少根的子节点的值字段。因此我认为 BaseNode 序列化 _M_left 和 _M_right 指针是可能的。但是由于_Node_base不知道_Node的值类型,所以看起来很难将“ar.register_type”添加到_Node_base.serialize()中。

【问题讨论】:

  • 该代码无法编译。 Node 应该是 BaseNode 的子类,leftright 应该是 ptrs,value_type 未声明,serialize 缺少返回类型等。请发布一些真实的代码(编译)。

标签: c++ serialization tree boost-serialization


【解决方案1】:

pointer_conflict 异常documentation 状态(原文如此):

    pointer_conflict,   // an attempt has been made to directly
                        // serialization::detail an object
                        // after having already serialzed the same
                        // object through a pointer.  Were this permited,
                        // it the archive load would result in the
                        // creation of an extra copy of the obect.

我认为冲突发生在每个由BaseNode::serialize 中的ptr 和Node::serialize 中的直接对象*Node 表达式序列化的地方。但是,由于 base_object 函数需要引用而不是 ptr,因此我不确定您将如何避免这种情况。

一种可能性是不序列化parent ptr。相反,在反序列化之后,遍历树并修复父 ptrs 以指向节点父节点。例如。将以下方法添加到 BaseNode :

void fix (BaseNode* parent = 0)
{
    this->parent = parent;
    if (left != 0)
        left->fix (this);
    if (right != 0)
        right->fix (this);
}

那就直接拨打root-&gt;fix ()

【讨论】:

  • 它仍然有一个从解码过程中引发的流错误......我在想它
  • 好友类 boost::serialization::access; template void serialize(Archive & ar, const unsigned int version) { // 序列化基类信息 ar.register_type(static_cast<_node>(NULL)); ar & boost::serialization::base_object<_node_base>(*this); ar & _M_value;我将此函数添加到 libkdtree::_Node 中,但是,我认为这里的问题是 base_object 中的 serialize() 函数不会正确序列化 _left、_right 点,它只是将它们视为 _Node_base * 指针
【解决方案2】:

libkdtree++ 和 boost::serialization 的以下解决方案似乎可行:

// KDTree::_Node
friend class boost::serialization::access;
template<class Archive>
//void serialize(Archive & ar, const unsigned int version)
void save(Archive & ar, const unsigned int version) const
{
  ar.register_type(static_cast< _Link_type>(NULL));
  ar & boost::serialization::base_object<_Node_base>(*this);
  _Link_type left = static_cast<_Link_type>(_M_left);
  _Link_type right = static_cast<_Link_type>(_M_right);
  ar & left & right;
  ar & _M_value;
}


template<class Archive>
void load(Archive & ar, const unsigned int version)
{
    ar.register_type(static_cast< _Link_type>(NULL));
    ar & boost::serialization::base_object<_Node_base>(*this);
    _Link_type left, right;
    ar & left & right;
    ar & _M_value;
    if (left) {
       left->_M_parent = this;
    } 
    if (right) {
       right->_M_parent = this;
    }
    _M_left = left;
    _M_right = right;
}

BOOST_SERIALIZATION_SPLIT_MEMBER()

【讨论】:

    猜你喜欢
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    • 2011-09-21
    • 1970-01-01
    • 2017-06-26
    • 2013-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多