C++ | boost库 类的序列化
是的,这是今年的情人节,一篇还在研究怎么用的文章,文结的时候应该就用成功了. 恩,要有信心
神奇的分割线
不知何时装过boost库的header-only库, 所以ratslam中的boost是可以编译的,但是我自己试的程序会编译不过, 提示错误是未定义的引用. 所以我就从安装boost库开始.
1. 到www.boost.org下载相应的库, 目前最新是1_60_0版本的链接打开
文件有点大
下载好后就可以安装了.
1. 我将文件解压缩在home目录下命名为BOOST_ROOT目录下.
2. cd BOOST_ROOT
3. ./bootstrap.sh --help
4. ./bootstrap.sh --prefix=/usr/local ##其实默认情况下prefix的值就是/usr/local
这句命令编译可执行文件到/usr/local目录下了,因此后面当你在程序中需要引用头文件依赖时,就在这个路径下
编译会有点慢. 编译完成后会生成bjam可执行文件
5. 编译完成后,安装bjam ./bjam install
安装完成,可以测试一下以下代码能否成功编译:
demo.cpp
#include <iostream>
#include <string>
#include <sstream> #include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp> #include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp> using namespace std; class Test
{
public: friend class boost::serialization::access; Test(bool b, char ch, int i, double d, string str)
: m_bool(b), m_char(ch), m_int(i), m_double(d), m_str(str)
{
} template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar& m_bool;
ar& m_char;
ar& m_int;
ar& m_double;
ar& m_str;
} private:
bool m_bool;
char m_char;
int m_int;
double m_double;
string m_str;
}; int main()
{
Test test(true, 'm', , 17.89, "fuzhijie"); stringstream binary_sstream;
stringstream text_sstream; long long begin, end; int size; //使用二进制的方式序列化
boost::archive::text_oarchive text_oa(text_sstream);
boost::archive::binary_oarchive binary_oa(binary_sstream); begin = time(NULL);
for(int i = ; i < ; ++i)
{
text_oa << test;
}
end = time(NULL); //哈,这里时间还可以这样用来计算程序执行时间,Mark size = text_sstream.tellp() / ( * ); cout << "text serialization seconds: " << end - begin << ", space: " << size << endl; begin = time(NULL);
for(int i = ; i < ; ++i)
{
binary_oa << test;
}
end = time(NULL); //以MB为单位
size = binary_sstream.tellp() / ( * ); cout << "binary serialization seconds: " << end - begin << ", space: " << size << endl; return ;
};
编译:
g++ -o main demo.cpp -L/usr/local/lib -lboost_serialization
运行:
./main
会看到执行结果:
text serialization seconds: , space:
binary serialization seconds: , space:
安装成功!
程序解读:
首先,我用的序列化通篇都是嵌入式实现的. (机智的你一定在之前了解过序列化的嵌入式和非嵌入式的区别了)
用serialist的时候的一般步骤是:
1 先引用头文件,
2 在类的声明中, 你需要一个序列化函数,该函数的一般格式是:
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{ //version是版本号
ar& m_str;
}
这样声明了你要序列化的数据之后, 你就完成了一半了
3 使用时是这样的, 因为你是要存储真实的数据,而类里面的声明只是告诉程序去序列化哪些变量. 因此, 首先你需要一个类的实例, 对象的创建过程中, 可以在任何时候给它的变量赋值,文上的程序是在初始化列表赋值的.
当你有了一个对象时, 你就有了明确要保存的数据了
4 定义一个序列化的对象
boost::archive::text_oarchive text_oa(text_sstream);//文本方式
boost::archive::binary_oarchive binary_oa(binary_sstream);//二进制方式
文末附: 何时用文本方式何时用二进制文件
5 定义了序列化对象, 就可以将数据流写入了
binary_oa << test; //将对象test的序列化数据以二进制存储形式写入内存
这样, 一个数据的序列化程序就完成了. 但是对于我这个还在学习C++的人来说, 似乎对容器和模板的操作没有很熟练啊, 如果要想序列化STL容器该怎么办呢?
序列化STL容器
#include<boost/serialization/list.hpp>
class bus_route
{
friend class boost::serialization::access;
std::list<bus_stop> stop;
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & stop; //会自动加上容器的长度
}
public:
bus_route(){}
};
这样序列化的声明就完成了
使用时,在主函数中
{
std::ofstream ofs( "store.dat" );
boost::archive::text_oarchive ar(ofs); ar & lv; //lv是你上面声明序列化的那个类的对象
ofs.close();
}
ps:序列化写完之后要用到FOREACH遍历一遍vector template, 记得是自己用的第一个或者第二个boost函数有些笔记的,然很开心来找,发现只有个标题的草稿,真想抽死自己,这个写完去填foreach的坑呀
附: 二进制文件文本文件的选择
1、二进制文件是把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放,也就是说存放的是数据的原形式。
2、文本文件是把数据的终端形式的二进制数据输出到磁盘上存放,也就是说存放的是数据的终端形式。
一、如果要存储字符数据,无论是放在文本文件还是放在二进制文件中都和内存中的数据形式是没有区别的.同样也和终端形式没有区别。那么在存储和显示的特性上也没有任何区别,不浪费存储空间也不浪费转换时间。所以如果一个文件只存放字符数据,那么讨论该文件是用文本文件或是二进制文件是没有任何意义的。
二、如果要存储非字符数据,则情况要复杂一些。
1、如果您需要频繁地保存和访问数据.那么应该采用二进制文件进行存放,这样可以节省存储空间和转换时间。
2、如果您需要频繁地向终端显示数据或从终端读人数据,那么应该采用文本文件进行存放,这样可以节省转换时间。windows中文本方式写时,存在''\n''->''\r\n''的转换,而二进制方式无转换.文本方式读时存在''\r\n''->至''\n''的转换,而二进制方式无转换.
linux中文本方式的读写与二进制方式的读写无差别,不存在回车换行间的转换.这样当直接在windows和linux中共享文件时,将会出现与回车换行相关的问题
C++ | boost库 类的序列化的更多相关文章
- boost库----enable_shared_from_this类的作用和实现原理
使用boost库时,经常会看到如下的类 class A:public enable_share_from_this<A> 在什么情况下要使类A继承enable_share_from_thi ...
- (七)boost库之单例类
(七)boost库之单例类 一.boost.serialzation的单件实现 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一 ...
- 漫步Facebook开源C++库Folly之string类设计(散列、字符串、向量、内存分配、位处理等,小部分是对现有标准库和Boost库功能上的补充,大部分都是基于性能的需求而“重新制造轮子”)
就在近日,Facebook宣布开源了内部使用的C++底层库,总称folly,包括散列.字符串.向量.内存分配.位处理等,以满足大规模高性能的需求. 这里是folly的github地址:https:// ...
- [C/C++] C/C++延伸学习系列之STL及Boost库概述
想要彻底搞懂C++是很难的,或许是不太现实的.但是不积硅步,无以至千里,所以抽时间来坚持学习一点,总结一点,多多锻炼几次,相信总有一天我们会变得"了解"C++. 1. C++标准库 ...
- json 对c++类的序列化(自动生成代码)
[动机] 之前写网络协议的时候,使用的是google protobuf,protobuf不但在性能和扩展性上有很好的优势,protoc自动生成c++类代码的工具,这点确实给程序员带来了很多便利. 做后 ...
- boost库(条件变量)
1相关理念 (1)类名 条件变量和互斥变量都是boost库中被封装的类. (2)条件变量 条件变量是thread库提供的一种等待线程同步的机制,可实现线程间的通信,它必须与互斥量配合使用,等待另一个线 ...
- boost库区间range基本原理及使用实例
由 www.169it.com 搜集整理 区间的概念类似于STL中的容器概念.一个区间提供了可以访问半开放区间[first,one_past_last)中元素的迭代器,还提供了区间中的元素数量的信息. ...
- boost库在windows下的编译和使用
因为跨平台的原因,现在要使用到boost库,boost库非常大,现在处于摸索阶段. 首先来说boost库在window下的安装和使用. 一.下载 首先从boost官方主页http://www.boos ...
- Boost库
2014-08-31 Boost库是一个经过千锤百炼.可移植.提供源代码的C++库,作为标准库的后备,是C++标准化进程的发动机之一.Boost库由C++标准委员会库工作组成员发起,其中有些内容有望成 ...
随机推荐
- mac 启动 docker daemon
我是用virtualbox安装的. 有一个小问题就是启动docker服务时会检查boot2docker是不是最新的. 由于github被封了,所以只能手动下 https://github.com/bo ...
- NET基础(2):类型转换
CLR最重要的特性之一就是类型安全的.在运行时,CLR总是知道对象的类型是什么.调用GetType()方法可以知道对象的确切类型,由于它是非虚方法,所以一个类型不可能伪装成另一种类型.每种编程语言都规 ...
- IE10,IE11下cookie无法写入问题
asp.net 4.0的程序,发布后,测试在ie6,ie7,ie8,ie9下均可以正常登录,但是在ie10,ie11下就是无法保存cookie,排查了一下是否ie10,ie11是否存在设置问题发下并不 ...
- n皇后2种解题思路与代码-Java与C++实现
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了n皇后问题的解题思路,并分别用java和c++实现了过程,最后,对于算法改进 ...
- 面试:浅谈tcp/udp
tcp是一种面向连接的.可靠的.基于字节流的传输层通信协议.是专门为了在不可靠的互联网络上提供一个可靠的端到端字节流而设计的,面向字节流. udp(用户数据报协议)是iso参考模型中一种无连接的传输层 ...
- Docker 在6.4上安装
1 在 CentOS 6.4 上安装 docker docker当前官方只支持Ubuntu,所以在 CentOS 安装Docker比较麻烦(Issue #172). docker官方文档说要求Li ...
- Git错误non-fast-forward后的冲突解决
Git错误non-fast-forward后的冲突解决当要push代码到git时,出现提示: error:failed to push some refs to ... Dealing with “n ...
- idea集成git
这几天刚刚用了idea编辑器.用起来感觉相比eclipse有很大优势.其中我觉得特别引人注意的一个优势就是与git的集成开发.git作为一个代码维护的平台和idea结合使用对团队开发有很大意义.本人是 ...
- Linux之常用快捷键
tab:自动补齐命令或者路径 ESC+u:将字符小写变大写 ctrl+s:在终端中冻结stdin ctrl+q:在终端中恢复stdin ctrl+a:光标移动到行首 ctrl+e:光标移动到行尾 ct ...
- 关于Unity四元数相乘先后顺序的问题
在unity中四元数和向量相乘在unity中可以变换旋转.四元数和四元数相乘类似矩阵与矩阵相乘的效果. 矩阵相乘的顺序不可互换,只有特殊条件矩阵才可互换.四元数相乘类似,今天就因为这个问题掉进坑里了, ...