Serialization 增强序列化和指向父类的指针
假设以下简化代码: 父类Serialization 增强序列化和指向父类的指针,serialization,boost,Serialization,Boost,假设以下简化代码: 父类 #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/serialization/unique_ptr.hpp> class Parent { public: Parent(); ... priva
#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 };
}
#包括
#包括
#包括
班级家长
{
公众:
父项();
...
私人:
//推进序列化
好友类boost::serialization::access;
模板
无效序列化(存档和ar,常量未签名整数版本)
{
ar&mèu child;
}
std::唯一的\u ptr m_child;
}
父::父()
{
...
m_child=std::unique_ptr(新子(this));
}
儿童班
#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 };
}
#包括
#包括
#包括
班童
{
公众:
子(父*父)
{
m_parent=父母;
};
...
私人:
//推进序列化
好友类boost::serialization::access;
模板
无效序列化(存档和ar,常量未签名整数版本)
{
ar&m_母公司;
}
Child(){};
父m_父{nullptr};
}
我的父类创建一个子类,并传递一个指向子类存储的自身的指针。
在归档父类时,它归档子类,该子类归档指向父类的指针。
还原父类时,它会创建子类并将其还原。我的问题是:
子类中的指针是否能够正确还原,从而保证指向其父类
我通过单步调试并将父级的This指针的值与子级的m_父级的值进行比较,验证了这一点。然而,我不知道boost是如何做到这一点的,这让我怀疑自己是否只是“走运”。有人能验证boost序列化是否足够聪明,可以维护child::m_parent->parent关系吗
或者我应该采取额外的步骤,不存档指针并在加载对象后设置它吗?两件事:
- 促进了这一点。序列化指针时,默认情况下启用对象跟踪
- 不,您不会像那样序列化
唯一\u ptr
m_父级
,因为父级可以从加载处理程序中设置自引用
但假设您想要简单的方法,让我们坚持这个想法,并使其工作,由于目标跟踪
演示
我包括了一些技巧来演示反序列化
- 更正指向同一对象的重复数据消除指针
- 即使在反序列化之前强制“中断”不变量,也会恢复成员指针
#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);
}
}
两件事:
- 促进了这一点。序列化指针时,默认情况下启用对象跟踪
- 不,您不会像那样序列化
唯一\u ptr
m_父级
,因为父级可以从加载处理程序中设置自引用
但假设您想要简单的方法,让我们坚持这个想法,并使其工作,由于目标跟踪
演示
我包括了一些技巧来演示反序列化
- 更正指向同一对象的重复数据消除指针
- 即使在反序列化之前强制“中断”不变量,也会恢复成员指针
#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);
}
}
对不起,输入错误,应该是:Parent*m_Parent{nullptr};对不起,输入错误,应该是:Parent*m_Parent{nullptr};