0、想写自己的二进制,不知道从何学起
为了写一套自己的二进制IO流,我翻了一遍boost的实现;这里讲输出binary部分
省流助手,
1、如果想实现基础类型的二进制流输出
去找 basic_binary_oprimitive类里的 save函数的实现 (在binary_orachinve_impl的构造里进行
了一次 os.rebuf() )
2、如果想实现像boost一样的类的二进制输出,
请结合源码,参悟下面图类继承图里的左侧类图里的实现(又臭又长)
我写文章的规范不太行,技术不强讲的也不是很深入,部分实现需要大家自己跟着源码去参悟。
首先,主要在网上找到的都是boost二进制的用法 没有讲到具体实现的原理,唯一找到的底层实现就写了个开头(不过这个大佬给的图倒是很方便使用)
图引用自这里:Boost序列化学习之二——binary_oarchive追本溯源_orsinozhu的专栏-优快云博客
我自己是对着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的专栏-优快云博客 这篇博客里讲的 侵入式和非侵入式的自定义类序列化方法。
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 的输出
自此 数据输出到流的实现其实就看完了。 就能开始写自己的基础类实现了。