使用 boost::serialization 的序列化树结构

发布于 2024-09-11 02:03:09 字数 929 浏览 8 评论 0原文

我必须在程序中序列化 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;
  }
}

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

I have to serialize libkdtree++ in my program, the tree structures are briefly described as following:

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;
  }
}

This program reports "stream error".
But from the "serailzed file", it lacks the value fields for the children nodes of roots. Thus I think it is possible that BaseNode serialized _M_left and _M_right pointer. However since _Node_base have no idea about the value type of _Node, so it looks hard to add "ar.register_type" to _Node_base.serialize().

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晨光如昨 2024-09-18 02:03:10

point_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.

:认为冲突发生在每个由 BaseNode::serialize 中的 ptr 序列化以及通过 Node::serialize< 中的直接对象 *Node 表达式序列化的情况下。 /代码>。但是,由于 base_object 函数采用引用而不是 ptr,我不确定如何避免这种情况。

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

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

然后只需调用 root->fix ()

The pointer_conflict exception documentation states (sic):

    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.

I think the conflict occurs where each is serialised by a ptr in BaseNode::serialize and via the direct object, the *Node expression, in Node::serialize. However since the base_object function takes a reference and not a ptr I'm not sure how you would avoid this.

One possibility is to not serialize the parent ptr. Instead, after deserialization, do a walk of the tree and fix up the parent ptrs to point to the node parent. E.g. add the following method to BaseNode :

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

Then just call root->fix ()

太阳哥哥 2024-09-18 02:03:10

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

The following solution for libkdtree++ & boost::serialization seems work:

// 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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文