假设以下简化代码:
家长班
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/unique_ptr.hpp>
class Parent
{
public:
Parent();
...
private:
// boost serialization
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & *m_child;
}
std::unique_ptr<Child> m_child;
}
Parent::Parent()
{
...
m_child = std::unique_ptr<Child>(new Child(this));
}
儿童课
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/unique_ptr.hpp>
class Child
{
public:
Child(Parent * parent)
{
m_parent = parent;
};
...
private:
// boost serialization
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & m_parent;
}
Child(){};
Parent m_parent{ nullptr };
}
我的父类创建一个子类,并将指针传递给子项存储的自身。 归档父类时,它会归档将指针归档到父级的子级。 恢复父类时,它会创建子类并恢复它。我的问题是:
子类中的指针是否会正确恢复,因此可以保证指向它的父级?
这个SEEMS可以通过逐步调试调试器并将Parent的this指针值与子节点的m_parent进行比较来验证。但是,我无法弄清楚助力如何将其拉下来,这让我想知道我是否只是“幸运”。任何人都可以验证boost序列化是否足够智能以维持child :: m_parent-&gt;父关系?
或者我应该采取额外的步骤:不加载指针并在加载对象后设置它?
答案 0 :(得分:0)
两件事:
Object Tracking为此提供了便利。在序列化指针时,默认情况下启用对象跟踪。
不,您没有像这样序列化unique_ptr
。
事实上,没有理由将序列化孩子的
m_parent
,因为父母可以在加载处理程序中设置自引用。 < / p>但是假设您想要简单的方法,让我们坚持这个想法并使其成为可能因为对象跟踪
我提供了一些技巧来证明反序列化
<强> Live On Coliru 强>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/unique_ptr.hpp>
#include <memory>
#include <sstream>
#include <iostream>
class Parent;
class Child {
public:
Child(Parent *parent)
: m_parent(parent), m_duplicate_parent(parent) {}
Parent *m_parent { nullptr };
Parent *m_duplicate_parent{ nullptr };
private:
friend class boost::serialization::access;
template <class Archive> void serialize(Archive &ar, unsigned) {
ar & m_parent & m_duplicate_parent;
}
Child() = default;
};
class Parent {
public:
Parent() : m_child(std::make_unique<Child>(this)) {}
//private:
friend class boost::serialization::access;
template <class Archive> void serialize(Archive &ar, unsigned) {
ar & m_child;
}
std::unique_ptr<Child> m_child;
};
int main() {
std::stringstream ss;
{
boost::archive::text_oarchive oa(ss);
Parent p;
assert(&p == p.m_child->m_parent);
assert(&p == p.m_child->m_duplicate_parent);
oa << p;
}
std::cout << ss.str();
{
boost::archive::text_iarchive ia(ss);
Parent p;
// let's purposelly break the invariants so we know deserialization
// does restore them as required, and we not just "getting lucky":
p.m_child->m_parent = nullptr;
p.m_child->m_duplicate_parent = nullptr;
assert(&p != p.m_child->m_parent);
assert(&p != p.m_child->m_duplicate_parent);
// nuclear:
p.m_child.reset();
// now deserialize
ia >> p;
assert(&p == p.m_child->m_parent);
assert(&p == p.m_child->m_duplicate_parent);
}
}
打印类似于
的内容22 serialization::archive 15 1 0
0 0 0 2 1 0
1 0 0 0 0