Boost 序列化 Serialization 底层实现
0、想寫自己的二進制,不知道從何學(xué)起
為了寫一套自己的二進制IO流,我翻了一遍boost的實現(xiàn);這里講輸出binary部分
省流助手,
1、如果想實現(xiàn)基礎(chǔ)類型的二進制流輸出
? ? ? 去找 basic_binary_oprimitive類里的 save函數(shù)的實現(xiàn) (在binary_orachinve_impl的構(gòu)造里進行
了一次 os.rebuf() )
2、如果想實現(xiàn)像boost一樣的類的二進制輸出,
? ? ??請結(jié)合源碼,參悟下面圖類繼承圖里的左側(cè)類圖里的實現(xiàn)(又臭又長)
我寫文章的規(guī)范不太行,技術(shù)不強講的也不是很深入,部分實現(xiàn)需要大家自己跟著源碼去參悟。
首先,主要在網(wǎng)上找到的都是boost二進制的用法 沒有講到具體實現(xiàn)的原理,唯一找到的底層實現(xiàn)就寫了個開頭(不過這個大佬給的圖倒是很方便使用)
圖引用自這里:Boost序列化學(xué)習(xí)之二——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, 然后把用重載&(本質(zhì)還是重載了<<)的方式實現(xiàn)數(shù)據(jù)輸出到oa。這里可以參考Boost - 序列化 (Serialization)_zj510的專欄-CSDN博客?這篇博客里講的 侵入式和非侵入式的自定義類序列化方法。
2、然后我們來講為什么boost的 binary_oarchive 繼承圖
關(guān)系為什么會這么深,然后繼承圖都是干嘛用的。
首先我們來看這個繼承圖的左側(cè),如果你看了源碼之后,你會發(fā)現(xiàn)看了一圈毫無軟用(當(dāng)然是有用的),根本沒有講到數(shù)據(jù)是如何變成二進制的實現(xiàn),因為這一塊主要實現(xiàn)的是 boost封裝了類、枚舉等的二進制輸出策略(應(yīng)該是)。
-如果你不想看這段可以直接跳到 第3段
?如果你想深入了解的話,save_override(~)這個函數(shù)是這一切的關(guān)鍵線索。
?這里開始就逐漸進入了知識盲區(qū),不過不重要,你會發(fā)現(xiàn),無論那一條路,最終都會走線一個函數(shù)實現(xiàn),那就是 ar.save(t) 這個函數(shù),
比如? mpl::identity<detail::save_non_pointer_type<Archive> > 這個類,最終的都會走到ar.save(t)這里只不過每條實現(xiàn)路徑的實現(xiàn)方法不一樣,參數(shù)的實現(xiàn)函數(shù)也略有不同。
然后這個save(其實就是我們需要的Binary輸出的主要實現(xiàn)函數(shù))
3、繼承圖里另一條繼承樹實現(xiàn) Binary輸出的實現(xiàn) save(T& t)
?首先能看的出來 save函數(shù) 對一些特殊基礎(chǔ)類還是做了特化的。
然后save函數(shù)實際調(diào)用的是 save_binary(const void *address, std::size_t count)
?save_binary(~~)里具體實現(xiàn)數(shù)據(jù)存儲的就是m_sb.sputn(~~)函數(shù)了
這里的m_sb其實是 之前boost archive聲明時候的 流對象?
sputn(~~)函數(shù)功能請看這里:?streambuf::xsputn - C++ Reference
---------------------------------------------------------------------------------------------------------
?Elem 和 Tr類的聲明 在?binary_oarchive類的構(gòu)造函數(shù)里就聲明好了
?這里的init的函數(shù)是個輸出默認(rèn) 頭文件的實現(xiàn),也是一個很好的輸出案例文件,
?binary_oarchive_impl 的init里包含了2個init()的實現(xiàn),
? ? ? ? ?1、一個是輸出版本號和默認(rèn)信息的?basic_binary_oarchive::init()
? ? ? ? ?2、另一個是輸出 int long float double 占多少字節(jié)書的輸出 (輸出都是char 大小的int值),并且還輸出了個 int(1)用來查看當(dāng)前系統(tǒng)是大段還是小段
4、結(jié)果
int temp = 123;
這里是 我? os& temp; 的結(jié)果? ?{? 才是int 123 的輸出??
?自此 數(shù)據(jù)輸出到流的實現(xiàn)其實就看完了。 就能開始寫自己的基礎(chǔ)類實現(xiàn)了。
總結(jié)
以上是生活随笔為你收集整理的Boost 序列化 Serialization 底层实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab maxfunevals,m
- 下一篇: 广西哪个学计算机电子大学好,广西大学和桂