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++标准委员会库工作组成员发起,其中有些内容有望成 ...
随机推荐
- Lua JSONRPC学习笔记
JSON RPC JSON RPC 为利用json数据格式来执行远程调用方式, 作用同xmlrpc,不过与xmlrpc相比, jsonrpc更加轻量,json更加节省数据量,更加可读性高. 官网网站: ...
- C++之路进阶——codevs2439(降雨量)
2439 降雨量 2007年省队选拔赛四川 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 大师 Master 题目描述 Description 我们常常会说这样的话 ...
- struts 初体验
1. 什么是Struts2 struts2是以WebWork的设计思想为核心,吸收了Struts1的部分有点,建立了兼容WebWork和Struts1的MVC框架. 1.1 WebWork: 强调系统 ...
- js方式找出数组中重复数最多的那个数,并返回该数以及重复次数
function findNum(a){ var result = [0,0]; for (var i = 0; i < a.length; i++) { for (var j = 0,coun ...
- 跟着8张思维导图学习javascript
学习的道路就是要不断的总结归纳,好记性不如烂笔头,so,下面将po出8张javascript相关的思维导图. 思维导图小tips:思维导图又叫心智图,是表达发射性思维的有效的图形思维工具 ,它简单却又 ...
- BeauifulSoup学习使用记录
BeautifulSoup的安装很简单pip install BeautifulSoup4 相关信息链接http://cuiqingcai.com/1319.html
- python :页面布局 ,后台管理页面之左侧菜单跟着滚动条动
左侧菜单跟着滚动条动 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http:// ...
- oracle 卸载
由于工作需要,重装了一下Oracle,然后发现同SQLServer,MySQL等数据库相比,Oracle的卸载重装真是不一般的麻烦. 整理了一下我的Oracle的卸载重装过程,给自己备忘,同时 ...
- WEB前端的原理及组成
1:认识WEB前端的组成部分和相关专业术语!具体的总结如下:
- 学习mongo系列(十一)关系
准备工作:首先在maxh数据库的address集合中先插入数据 > db.address.insert({child_address:"gansu"}) WriteResul ...