Boost序列化:用根内存管理序列化树
Boost Serialization: Serializing a tree with root memory management
我有一个自定义的树数据结构,我决定采用以下设置。我有一个Tree
类,普通指针向左,向右,向上(父),然后我有一个Root
类,继承自Tree
;根类处理所有内存管理。(树需要很快,所以我不能提供共享指针)。树中的每个节点都存在于根内存池中(因此left()
将指向内存池内部),每个指向某些Data
的指针也是如此:
class Root;
class Tree {
public:
inline Tree() : mLeft(nullptr), mRight(nullptr), mParent(nullptr),
mRoot(nullptr), mData(nullptr) {}
inline Tree *left() { return mLeft; }
inline Tree *right() { return mRight; }
inline Tree *parent() { return mParent; }
inline Root *root() { return mRoot; }
inline Data *data() { return mData; }
inline bool isLeaf() { return mData == nullptr; }
...
protected:
inline Tree(Tree *parent, Root *root) :
mLeft(nullptr), mRight(nullptr), mParent(parent), mRoot(root),
mData(nullptr) {}
Tree *mLeft;
Tree *mRight;
Tree *mParent;
Root *mRoot;
Data *mData;
};
class Root : public Tree {
friend class Tree;
public:
inline Root() : Tree(nullptr, this) {}
private:
MemoryPool<Data> mDataSpace; // behaves like std::set for the purposes of this example
MemoryPool<Tree> mNodeSpace;
};
如果我想分割一个节点,Tree
类使用它的mRoot
引用来分配新的子节点。
我现在想序列化树。Boost提供了一个非常好的序列化库,但我不确定如何使它适合我当前的设置。理想情况下,我想写:
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
ar & mParent;
ar & mRoot;
if (!isLeaf()) {
left()->serialize(ar, version);
ar & mLeft;
ar & mRight;
ar & mData;
right()->serialize(ar, version);
}
}
我很确定这将在保存时工作得很好,但是加载呢?每个节点在成为其他节点的子节点之前都需要在mDataSpace
中进行分配。那么父节点呢?我认为Boost的序列化不够聪明,如果不先做一些额外的工作,就无法实现这些细节,对吧?
更复杂的是,结构Data
是不可变的,我不能为它编写侵入式序列化。要序列化,我可以使用ar & data.x()
,但要反序列化,我需要编写data = Data(x);
。
我假设我将不得不为Tree
编写某种特殊的构造函数,该构造函数为Tree
成员left
等在根节点的内存容器中分配一些空间?
是的,你在正确的轨道上。要获得Boost序列化来实例化动态对象(Node/Data),您需要实现
-
save_construct_data
和 -
load_construct_data
你可以在Data
类的上下文中读到这一点,它们不是默认可构造的: http://www.boost.org/doc/libs/1_59_0/libs/serialization/doc/serialization.html#constructors
现在,对于中央分配,您可以使用相同的方法。但是,我建议简单地序列化mDataSpace
和mNodeSpace
容器,并将索引序列化到它们中,而不是使用boost来序列化所有跟踪的对象引用,这可能要容易得多。
这将不那么棘手和更有效,因为Boost序列化不需要做对象跟踪。更重要的是,您只需要确保根在任何节点之前序列化,就可以了。
Out Of The Box:开箱即用,我已经实现了同样的事情,但使用Boost侵扰为我实际做树算法。Boost侵扰型容器实际上不拥有它们的元素,树的根的表示方式与这里的表示方式基本相同。因此,您可以拥有节点存储+侵入式容器的元组,并免费获得所有实现细节。
- 如何在C++中序列化结构数据
- 序列化,没有库的整数,得到奇怪的结果
- 如何知道QDataStream不能反序列化某些内容
- 如何使用Python从C++中读取谷物序列化数据
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- 带有Protobuf序列化的C++Hazelcast:字符串不是UTF-8格式的
- 自定义对象的dlib序列化在gcc中失败
- C++boost序列化多态性问题
- 增强基于 XML class_id的反序列化
- 提升反序列化对象具有 nan 或 -nan 值
- 在 cpp 中的平面缓冲区中序列化对象
- 每次进行继承时都需要提升::序列化::base_object吗?
- 如何在 c++ 非托管代码中反序列化 byte[] 的 json 字符串?
- 提升序列化 1:73 的向后兼容性问题
- 将 boost 序列化对象的 asio::streambuf 表示转换为 Beast 的 DynamicBody req.body()
- 为什么 nlohmann/json 序列化 "null" 而不是在 double 上"0"?
- 如何反序列化数组?
- 如何使用提升序列化?
- 序列化多晶型接口
- Boost序列化:用根内存管理序列化树