如何以最小代码改动使用boost::serialization读写嵌套非POD结构体?
使用boost::serialization为非POD嵌套结构体实现文件读写(最小改动方案)
刚好碰到过类似的多层嵌套结构体改用vector后的序列化问题,boost::serialization完全能在几乎不改动现有NewA、NewB结构体核心定义的前提下解决文件读写的问题,而且对7层嵌套的结构体也能自动递归处理,不用手动逐层编写逻辑。
核心思路
boost::serialization的优势在于它可以自动识别并处理std::vector这类标准容器,同时只需要给每个自定义结构体添加一小段序列化逻辑(完全不修改原有成员),就能实现完整的序列化/反序列化,完美规避非POD类型的手动读写复杂度。
具体实现步骤(改动极小)
引入必要头文件
需要包含boost序列化相关的头文件,以及标准文件流头文件:#include <boost/serialization/vector.hpp> #include <boost/serialization/access.hpp> #include <fstream> #include <cassert>给每个结构体添加序列化友元函数
这是唯一需要修改结构体的地方,而且只是在结构体内部添加一个私有友元函数,完全不改动原有成员变量和初始化逻辑:struct NewA { std::vector<int> Value; char SomeChar = 'a'; // 新增:序列化逻辑,仅需这几行 private: friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & Value; ar & SomeChar; } }; struct NewB { std::vector<NewA> data; float SomeFloat = 0.1f; // 新增:序列化逻辑 private: friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & data; ar & SomeFloat; } };这里的
serialize函数会告诉boost如何序列化结构体的每个成员,对于嵌套的std::vector<NewA>,boost会自动递归调用NewA的序列化函数,哪怕嵌套7层也一样有效。实现文件读写操作
读写逻辑非常简洁,不需要手动处理内存、大小计算,直接用boost的文本归档(也可以用二进制归档,更高效):int main() { // 初始化对象并赋值示例 NewB StructNewBObject = {}; StructNewBObject.data.emplace_back(); StructNewBObject.data[0].Value.push_back(100); StructNewBObject.data[0].Value.push_back(200); // 写入文件 std::ofstream ofs("data.txt"); boost::archive::text_oarchive oa(ofs); oa << StructNewBObject; // 从文件读取 NewB loadedObject; std::ifstream ifs("data.txt"); boost::archive::text_iarchive ia(ifs); ia >> loadedObject; // 验证读取结果 assert(loadedObject.SomeFloat == 0.1f); assert(loadedObject.data[0].SomeChar == 'a'); assert(loadedObject.data[0].Value[0] == 100); return 0; }
为什么这是最小改动方案?
- 原有结构体的成员定义、初始化逻辑完全不需要修改,只需要给每个结构体添加几行序列化函数代码;
- 多层嵌套的结构体,只要每层都添加了对应的
serialize函数,boost会自动递归处理,不需要手动编写嵌套遍历逻辑; - 不管是文本格式还是二进制格式的归档,都只需要替换对应的Archive类即可,核心逻辑不变。
内容的提问来源于stack exchange,提问作者BlueTune
相关产品推荐
相关产品推荐

