提升递归对象的序列化
Boost serialization of recursive objects
我定义了以下要序列化的类:
using namespace std;
class MyElementObject
{
friend class boost::serialization::access;
public:
template<class Archive>
void serialize(Archive & ar, const unsigned int version) { }
};
template<class T>
class MyRecursiveObject
{
friend class boost::serialization::access;
public:
T element;
std::vector<MyRecursiveObject<T> > children;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & element;
ar & children;
}
};
然后,我运行以下代码:
int main()
{
//MyRecursiveObject initialization
MyRecursiveObject<MyElementObject> rec_object;
rec_object.children.push_back(MyRecursiveObject<MyElementObject>());
rec_object.children[0].children.push_back(MyRecursiveObject<MyElementObject>());
//create vector of pointers to MyRecursiveObject's elements
vector<MyElementObject *> elt_ptrs;
elt_ptrs.push_back(&rec_object.element);
elt_ptrs.push_back(&rec_object.children[0].element);
elt_ptrs.push_back(&rec_object.children[0].children[0].element);
//serialize MyRecursiveObject and the vector of pointers
{
ofstream ofs("filename");
boost::archive::text_oarchive oa(ofs);
oa << rec_object;
oa << elt_ptrs;
}
//create new MyRecursiveObject and vector of pointers for deserialization
MyRecursiveObject<MyElementObject> rec_object_deserialized;
rec_object_deserialized.children.push_back(MyRecursiveObject<MyElementObject>());
rec_object_deserialized.children[0].children.push_back(MyRecursiveObject<MyElementObject>());
vector<MyElementObject *> elt_ptrs_deserialized;
//deserialize
{
ifstream ifs("filename");
boost::archive::text_iarchive ia(ifs);
ia >> rec_object_deserialized;
ia >> elt_ptrs_deserialized;
}
//compare deserialized pointers
cout<<"elt_ptrs first level="<<elt_ptrs_deserialized[0]
<<" expected="<<&rec_object_deserialized.element<<endl;
cout<<"elt_ptrs second level="<<elt_ptrs_deserialized[1]
<<" expected="<<&rec_object_deserialized.children[0].element<<endl;
cout<<"elt_ptrs third level="<<elt_ptrs_deserialized[2]
<<" expected="<<&rec_object_deserialized.children[0].children[0].element<<endl;
return 0;
}
我总是得到类似于以下内容的输出:
elt_ptrs first level=0x7fff57c787c0 expected=0x7fff57c787c0
elt_ptrs second level=0x18e7020 expected=0x18e7020
elt_ptrs third level=0xffff8000ab5564f0 expected=0x18e7450
从指针值可以看出,我设法反序列化指向元素的指针,这些指针向下指向MyRecursiveObject的第二个递归级别。一旦我尝试使用指向第三级甚至更深层次的指针来执行此操作,反序列化就会失败。
我是否错误地使用了 boost::序列化?
请注意,MyRecursiveObject 始终成功反序列化,无论它有多少递归级别。我只遇到反序列化指向其元素的指针的问题。
提前谢谢你基恩
让我们先来看看出了什么问题。默认容器反序列化程序基本上是这样工作的:
size_t count;
ar >> BOOST_SERIALIZATION_NVP(count); // get element count
while( count-- > 0 ) {
T temp; // <- and here's the problem!
ar >> boost::serialization::make_nvp("item",temp);
container.push_back(temp);
}
容器(在您的情况下是vector<MyRecursiveObject<T>>
)使用局部变量填充。不幸的是,他们的地址被注册(对象跟踪)并在您反序列化vector<MyElementObject*>
时被引用。换句话说,您的elt_ptrs_deserialized
指向早已消失的局部变量。
要解决此问题,请在不使用局部变量的情况下手动序列化向量:
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(element);
size_t count = children.size(); // 0 when loading, N when storing
ar & BOOST_SERIALIZATION_NVP(count); // load or store element count
children.resize(count); // should be a no-op when storing
while( count-- > 0 )
ar & boost::serialization::make_nvp("item",children[count]);
}
// You should split serialize() into load() and save() with
// BOOST_SERIALIZATION_SPLIT_MEMBER() for a cleaner version
现在,首先分配整个向量的内存,并将元素直接反序列化到其中,从而注册正确的内存地址。这应该产生所需的结果:
elt_ptrs 1st level=0x22fe90 expected=0x22fe90
elt_ptrs 2nd level=0x6127d0 expected=0x6127d0
elt_ptrs 3rd level=0x613d50 expected=0x613d50
elt_ptrs 4th level=0x613c88 expected=0x613c88
相关文章:
- 提升反序列化对象具有 nan 或 -nan 值
- 在 cpp 中的平面缓冲区中序列化对象
- 将 boost 序列化对象的 asio::streambuf 表示转换为 Beast 的 DynamicBody req.body()
- 从一个文件中读取多个序列化对象
- 具有GSOAP的序列化对象,以验证Web服务输出
- 促进序列化对象为json
- 使用 FlatBuffers 序列化对象的向量
- 是否可以简单地序列化C++对象
- C 用向量序列化对象会导致双重自由损坏
- 用C++序列化对象的首选方式
- 序列化C++对象
- 如何在不存在任何数据损坏风险的情况下序列化对象
- 如何使用boost::序列化将对象的矢量作为属性序列化对象
- C++:如何在不使用库的情况下序列化/反序列化对象
- 写入函数是否在 C++ 中使用 ASCII 序列化对象
- 如何从 QDataStream 中读取多个相同类型的序列化对象
- 在C++中反序列化对象
- 在Qt中序列化对象图有哪些方法
- 使用 mixins 序列化/反序列化对象
- 序列化对象时丢失名称