3

我必须在我的程序中序列化 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()。

4

2 回答 2

0

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

    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.

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

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

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

然后打电话root->fix ()

于 2010-07-23T17:00:42.320 回答
0

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()
于 2010-08-05T09:02:33.880 回答