Boost 序列化 Serialization 底层实现

0、想写自己的二进制,不知道从何学起

为了写一套自己的二进制IO流,我翻了一遍boost的实现;这里讲输出binary部分

省流助手,

1、如果想实现基础类型的二进制流输出
      去找 basic_binary_oprimitive类里的 save函数的实现 (在binary_orachinve_impl的构造里进行
了一次 os.rebuf() )


2、如果想实现像boost一样的类的二进制输出
      请结合源码,参悟下面图类继承图里的左侧类图里的实现(又臭又长)

我写文章的规范不太行,技术不强讲的也不是很深入,部分实现需要大家自己跟着源码去参悟。

首先,主要在网上找到的都是boost二进制的用法 没有讲到具体实现的原理,唯一找到的底层实现就写了个开头(不过这个大佬给的图倒是很方便使用)

图引用自这里:Boost序列化学习之二——binary_oarchive追本溯源_orsinozhu的专栏-CSDN博客

我自己是对着boost 1.75的版本写的,

1、首先先从使用讲起  :

	int temp = 123;
	
    //第一种 写入到文件流
	fstream ostream("b.dat", ios::out | ios::binary);
	boost::archive::binary_oarchive oa(ostream);
	oa& BOOST_SERIALIZATION_NVP(temp);//简单的写法是 oa& temp;

    //第二种 到string 流理
	stringstream ostream; 
	boost::archive::binary_oarchive oa(ostream);
	oa& BOOST_SERIALIZATION_NVP(temp);

实际上这里就是给 boost 序列器一个 输出流oa, 然后把用重载&(本质还是重载了<<)的方式实现数据输出到oa。这里可以参考Boost - 序列化 (Serialization)_zj510的专栏-CSDN博客 这篇博客里讲的 侵入式和非侵入式的自定义类序列化方法。

2、然后我们来讲为什么boost的 binary_oarchive 继承图

关系为什么会这么深,然后继承图都是干嘛用的。

首先我们来看这个继承图的左侧,如果你看了源码之后,你会发现看了一圈毫无软用(当然是有用的),根本没有讲到数据是如何变成二进制的实现,因为这一块主要实现的是 boost封装了类、枚举等的二进制输出策略(应该是)。

-如果你不想看这段可以直接跳到 第3段

 如果你想深入了解的话,save_override(~)这个函数是这一切的关键线索。

 这里开始就逐渐进入了知识盲区,不过不重要,你会发现,无论那一条路,最终都会走线一个函数实现,那就是 ar.save(t) 这个函数,
比如  mpl::identity<detail::save_non_pointer_type<Archive> > 这个类,最终的都会走到ar.save(t)这里只不过每条实现路径的实现方法不一样,参数的实现函数也略有不同。

然后这个save(其实就是我们需要的Binary输出的主要实现函数)

3、继承图里另一条继承树实现 Binary输出的实现 save(T& t)

 首先能看的出来 save函数 对一些特殊基础类还是做了特化的。

然后save函数实际调用的是 save_binary(const void *address, std::size_t count)

 save_binary(~~)里具体实现数据存储的就是m_sb.sputn(~~)函数了

这里的m_sb其实是 之前boost archive声明时候的 流对象 

sputn(~~)函数功能请看这里: streambuf::xsputn - C++ Reference

---------------------------------------------------------------------------------------------------------

 Elem 和 Tr类的声明 在 binary_oarchive类的构造函数里就声明好了

 这里的init的函数是个输出默认 头文件的实现,也是一个很好的输出案例文件,

 binary_oarchive_impl 的init里包含了2个init()的实现,
         1、一个是输出版本号和默认信息的 basic_binary_oarchive::init()
         2、另一个是输出 int long float double 占多少字节书的输出 (输出都是char 大小的int值),并且还输出了个 int(1)用来查看当前系统是大段还是小段

4、结果

int temp = 123;
这里是 我  os& temp; 的结果   {  才是int 123 的输出  

 自此 数据输出到流的实现其实就看完了。 就能开始写自己的基础类实现了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值