1.序列化和反序列化的作用
主要用于网络传输,因为类对象无法直接通过网络字节流传输,需要序列化为字节流后传输,再反序列化为类对象。
这种感觉有点像科幻中把人粒子化,传输后再还原。
序列化也被用于储存状态和还原,比如工作做到一半需要保存现场,后续需要继续做,则可通过序列化保存内存中的数据,也就是工作状态,下次载入即可。
2.使用方法
头文件和源文件都需要包含BoostArchiver.h
序列化分两种,嵌入式需要修改类代码,但是可以储存private成员;非嵌入式不用修改类代码,但是只能储存公共成员,一般推荐大家使用嵌入式。
使用方法为,在.h文件的类声明中加入序列化函数声明,并声明友类 boost::serialization::access,建议设置为private。
private:
// serialize is recommended to be private
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive &ar, const unsigned int version);
//在类的实现文件中加入
template<class Archive>
void XXX::serialize(Archive &ar, const unsigned int version)
{
ar & member1;
ar & member2;
...
}
template void Map::serialize(boost::archive::binary_iarchive&, const unsigned int);
template void Map::serialize(boost::archive::binary_oarchive&, const unsigned int);
这里需要提醒的是,ar后面的&实际是重载了<<和>>,会根据参数class Archive的不同决定是输入还是输出。
这样的好处是,可以保证序列化和反序列化顺序相同,也不用写两个函数。
“//binary_iarchive对应输入【反序列化】,binary_oarchive用于输出【序列化】
//使用&的好处在于可以用一个函数表示序列化<<和反序列化>>,参数列表不同即可
//根据是in/out决定是执行何项操作”
另外,boost的序列化是支持数组,STL容器的。
使用时需要自己写一对save/load,适当时使用,比如:
void System::SaveMap(const string &filename)
{
std::ofstream out(mapfile, std::ios_base::binary);
if (!out)
{
cerr << "Cannot Write to Mapfile: " << mapfile << std::endl;
exit(-1);
}
cout << "Saving Mapfile: " << mapfile << std::endl;
boost::archive::binary_oarchive oa(out, boost::archive::no_header);
oa << mpMap;
oa << mpKeyFrameDatabase;
cout << " ...done" << std::endl;
out.close();
}
bool System::LoadMap(const string &filename)
{
std::ifstream in(filename, std::ios_base::binary);
if (!in)
{
cerr << "Cannot Open Mapfile: " << mapfile << " , Create a new one" << std::endl;
return false;
}
cout << "Loading Mapfile: " << mapfile << std::flush;
boost::archive::binary_iarchive ia(in, boost::archive::no_header);
ia >> mpMap;
ia >> mpKeyFrameDatabase;
mpKeyFrameDatabase->SetORBvocabulary(mpVocabulary);
cout << " ...done" << std::endl;
cout << "Map Reconstructing" << flush;
vector<ORB_SLAM2::KeyFrame*> vpKFS = mpMap->GetAllKeyFrames();
for (auto it:vpKFS) {
it->SetORBvocabulary(mpVocabulary);
it->ComputeBoW();
}
cout << " ...done" << endl;
in.close();
return true;
}
参考资料:
https://blog.csdn.net/zj510/article/details/8105408
https://blog.csdn.net/zj510/article/details/8105408