• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            woaidongmao

            文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            Boost Serialization 庫教程

            輸出檔案(archive)類似于輸出數(shù)據(jù)流(stream)。數(shù)據(jù)能通過<< 或 & 操作符存儲(chǔ)到檔案(archive)中:

             
            ar << data;
            ar & data;

            輸入檔案(archive)類似于輸入數(shù)據(jù)流(stream)。數(shù)據(jù)能通過>> 或 & 操作符從檔案(archive)中裝載。

             
            ar >> data;
            ar & data;

            對于原始數(shù)據(jù)類型,當(dāng)這些操作調(diào)用的時(shí)候,數(shù)據(jù)是簡單的“被存儲(chǔ)/被裝載” “到/從” 檔案(archive)。對于類(class)數(shù)據(jù)類型,類的serialize 函數(shù)被調(diào)用。對上面的操作,每個(gè)serialize 函數(shù)用來“存儲(chǔ)/裝載”其數(shù)據(jù)成員。這個(gè)處理采用遞歸的方式,直到所有包含在類中的數(shù)據(jù)“被存儲(chǔ)/被裝載”。

             

            一個(gè)非常簡單的情形

            通常用serialize 函數(shù)來存儲(chǔ)和裝載類的數(shù)據(jù)成員。

            這個(gè)庫包含一個(gè)叫 demo.cpp 的程序,用于介紹如何用這個(gè)庫。下面,我們從這個(gè)demo摘錄代碼,來介紹這個(gè)庫應(yīng)用的最簡單情形。

             
            #include <fstream>
             
            // include headers that implement a archive in simple text format
            #include <boost/archive/text_oarchive.hpp>
            #include <boost/archive/text_iarchive.hpp>
             
            /////////////////////////////////////////////////////////////
            // gps coordinate
            //
            // illustrates serialization for a simple type
            //
            class gps_position
            {
            private:
                friend class boost::serialization::access;
                // When the class Archive corresponds to an output archive, the
                // & operator is defined similar to <<.  Likewise, when the class Archive
                // is a type of input archive the & operator is defined similar to >>.
                template<class Archive>
                void serialize(Archive & ar, const unsigned int version)
                {
                    ar & degrees;
                    ar & minutes;
                    ar & seconds;
                }
                int degrees;
                int minutes;
                float seconds;
            public:
                gps_position(){};
                gps_position(int d, int m, float s) :
                    degrees(d), minutes(m), seconds(s)
                {}
            };
             
            int main() {
                // create and open a character archive for output
                std::ofstream ofs("filename");
                boost::archive::text_oarchive oa(ofs);
             
                // create class instance
                const gps_position g(35, 59, 24.567f);
                // write class instance to archive
                oa << g;
                // close archive
                ofs.close();
             
                // ... some time later restore the class instance to its orginal state
                // create and open an archive for input
                std::ifstream ifs("filename", std::ios::binary);
                boost::archive::text_iarchive ia(ifs);
                // read class state from archive
                gps_position newg;
                ia >> newg;
                // close archive
                ifs.close();
                return 0;
            }
             

            對于每個(gè)通過序列化“被存儲(chǔ)”的類,必須存在一個(gè)函數(shù)去實(shí)現(xiàn)“存儲(chǔ)”其所有狀態(tài)數(shù)據(jù)。對于每個(gè)通過序列化“被裝載”的類,必須存在一個(gè)函數(shù)來實(shí)現(xiàn)“裝載”其所有狀態(tài)數(shù)據(jù)。在上面的例子中,這些函數(shù)是模板成員函數(shù)serialize。

             

            非侵入的版本

            在上例是侵入的設(shè)計(jì)。類是需要由其實(shí)例來序列化,來改變。這在某些情形是困難的。一個(gè)等價(jià)的可選的設(shè)計(jì)如下:

             
            #include <boost/archive/text_oarchive.hpp>
            #include <boost/archive/text_iarchive.hpp>
             
            class gps_position
            {
            public:
                int degrees;
                int minutes;
                float seconds;
                gps_position(){};
                gps_position(int d, int m, float s) :
                    degrees(d), minutes(m), seconds(s)
                {}
            };
             
            namespace boost {
            namespace serialization {
             
            template<class Archive>
            void serialize(Archive & ar, gps_position & g, const unsigned int version)
            {
                ar & g.degrees;
                ar & g.minutes;
                ar & g.seconds;
            }
             
            } // namespace serialization
            } // namespace boost

            這種情況生成的serialize 函數(shù)不是gps_position類的成員函數(shù)。這有異曲同工之妙。

            非侵入序列化主要應(yīng)用在不改變類定義就可實(shí)現(xiàn)類的序列化。為實(shí)現(xiàn)這種可能,類必須提供足夠的信息來更新類狀態(tài)。在這個(gè)例子中,我們假設(shè)類有public成員。僅當(dāng)提供足夠信息來存儲(chǔ)和裝載的類,才能不改變類自身,在外部來序列化類狀態(tài)。

             

            可序列化的成員

            一個(gè)可序列化的類,可擁有可序列化的成員,例如:

             
            class bus_stop
            {
                friend class boost::serialization::access;
                template<class Archive>
                void serialize(Archive & ar, const unsigned int version)
                {
                    ar & latitude;
                    ar & longitude;
                }
                gps_position latitude;
                gps_position longitude;
            protected:
                bus_stop(const gps_position & lat_, const gps_position & long_) :
                latitude(lat_), longitude(long_)
                {}
            public:
                bus_stop(){}
                // See item # 14 in Effective C++ by Scott Meyers.
                // re non-virtual destructors in base classes.
                virtual ~bus_stop(){}
            };

            這里,類類型的成員被序列化,恰如原始類型被序列化一樣。

            注意,類bus_stop的實(shí)例“存儲(chǔ)”時(shí),其歸檔(archive)操作符將調(diào)用latitude 和 longitude的serialize 函數(shù)。這將依次調(diào)用定義在gps_position中的serialize 來被“存儲(chǔ)”。這種手法中,通過bus_stop的歸檔(archive)操作符,整個(gè)數(shù)據(jù)結(jié)構(gòu)被存儲(chǔ),bus_stop是它的根條目。

             

            派生類

            派生類應(yīng)包含其基類的序列化。

             
            #include <boost/serialization/base_object.hpp>
             
            class bus_stop_corner : public bus_stop
            {
                friend class boost::serialization::access;
                template<class Archive>
                void serialize(Archive & ar, const unsigned int version)
                {
                    // serialize base class information
                    ar & boost::serialization::base_object<bus_stop>(*this);
                    ar & street1;
                    ar & street2;
                }
                std::string street1;
                std::string street2;
                virtual std::string description() const
                {
                    return street1 + " and " + street2;
                }
            public:
                bus_stop_corner(){}
                bus_stop_corner(const gps_position & lat_, const gps_position & long_,
                    const std::string & s1_, const std::string & s2_
                ) :
                    bus_stop(lat_, long_), street1(s1_), street2(s2_)
                {}
            };
             

            注意在派生類中不要直接調(diào)用其基類的序列化函數(shù)。這樣做看似工作,實(shí)際上繞過跟蹤實(shí)例用于存儲(chǔ)來消除冗余的代碼。它也繞過寫到檔案中類的版本信息的代碼。因此,總是聲明serialize 作為私有函數(shù)。聲明friend boost::serialization::access 將運(yùn)行序列化庫存取私有變量和函數(shù)。

             

            指針

            假設(shè)我們定義了bus route包含一組bus stops。假定:

            1. 我們可以有幾種bus stop的類型(記住bus_stop是一個(gè)基類)。
            2. 一個(gè)所給的 bus_stop可以展現(xiàn)多于一個(gè)的路線。

            一個(gè)bus route 用一組指向bus_stop的指針來描述是方便的。

             
            class bus_route
            {
                friend class boost::serialization::access;
                bus_stop * stops[10];
                template<class Archive>
                void serialize(Archive & ar, const unsigned int version)
                {
                    int i;
                    for(i = 0; i < 10; ++i)
                        ar & stops[i];
                }
            public:
                bus_route(){}
            };
             

            數(shù)組stops 的每個(gè)成員將被序列化。但是,記住每個(gè)成員是個(gè)指針。 - 實(shí)際含義是什么?序列化整個(gè)對象是要求在另一個(gè)地方和時(shí)間重新構(gòu)造原始數(shù)據(jù)結(jié)構(gòu)。用指針為了完成這些,存儲(chǔ)指針的值是不夠的,指針指向的對象必須存儲(chǔ)。當(dāng)成員最后被裝載,一個(gè)新的對象被創(chuàng)建,新的指針被裝載到類的成員中。

            所有這一切是由序列化庫自動(dòng)完成的。通過指針關(guān)聯(lián)的對象,上述代碼能完成存儲(chǔ)和裝載。

             

            數(shù)組

            事實(shí)上上述方案比較復(fù)雜。序列化庫能檢測出被序列化的對象是一個(gè)數(shù)組,將產(chǎn)生上述等價(jià)的代碼。因此上述代碼能更短的寫為:

             
            class bus_route
            {
                friend class boost::serialization::access;
                bus_stop * stops[10];
                template<class Archive>
                void serialize(Archive & ar, const unsigned int version)
                {
                    ar & stops;
                }
            public:
                bus_route(){}
            };
             
            STL容器

            上面的例子用數(shù)組成員。更多的如此的一個(gè)應(yīng)用用STL容器為如此的目的。序列化庫包含為所有STL容器序列化的代碼。因此,下種方案正如我們所預(yù)期的樣子工作。

             
            #include <boost/serialization/list.hpp>
             
            class bus_route
            {
                friend class boost::serialization::access;
                std::list<bus_stop *> stops;
                template<class Archive>
                void serialize(Archive & ar, const unsigned int version)
                {
                    ar & stops;
                }
            public:
                bus_route(){}
            };
             
            類的版本

            假設(shè)我們對bus_route類滿意,在產(chǎn)品中使用它。一段時(shí)間后,發(fā)覺bus_route 類需要包含線路駕駛員的名字。因此新版本如下:

             
            #include <boost/serialization/list.hpp>
            #include <boost/serialization/string.hpp>
             
            class bus_route
            {
                friend class boost::serialization::access;
                std::list<bus_stop *> stops;
                std::string driver_name;
                template<class Archive>
                void serialize(Archive & ar, const unsigned int version)
                {
                    ar & driver_name;
                    ar & stops;
                }
            public:
                bus_route(){}
            };
             

            好,完畢!異常...會(huì)發(fā)生在讀取舊版本所生成的數(shù)據(jù)文件時(shí)。如何考慮版本問題?

            通常,序列化庫為每個(gè)被序列化的類在檔案中存儲(chǔ)版本號(hào)。缺省值是0。當(dāng)檔案裝載時(shí),存儲(chǔ)的版本號(hào)可被讀出。上述代碼可修改如下:

             
            #include <boost/serialization/list.hpp>
            #include <boost/serialization/string.hpp>
            #include <boost/serialization/version.hpp>
             
            class bus_route
            {
                friend class boost::serialization::access;
                std::list<bus_stop *> stops;
                std::string driver_name;
                template<class Archive>
                void serialize(Archive & ar, const unsigned int version)
                {
                    // only save/load driver_name for newer archives
                    if(version > 0)
                        ar & driver_name;
                    ar & stops;
                }
            public:
                bus_route(){}
            };
             
            BOOST_CLASS_VERSION(bus_route, 1)
             

            對每個(gè)類通過應(yīng)用的版本,沒有必要維護(hù)一個(gè)版本文件。一個(gè)文件版本是所有它組成的類的版本的聯(lián)合。系統(tǒng)允許程序和以前版本的程序創(chuàng)建的檔案向下兼容。

             

            把serialize拆分成save/load

            serialize函數(shù)是簡單,簡潔,并且保證類成員按同樣的順序(序列化系統(tǒng)的key)被存儲(chǔ)/被裝載。可是有像這里例子一樣,裝載和存儲(chǔ)不一致的情形。例如,一個(gè)類有多個(gè)版本的情況發(fā)生。上述情形能重寫為:

             
            #include <boost/serialization/list.hpp>
            #include <boost/serialization/string.hpp>
            #include <boost/serialization/version.hpp>
            #include <boost/serialization/split_member.hpp>
             
            class bus_route
            {
                friend class boost::serialization::access;
                std::list<bus_stop *> stops;
                std::string driver_name;
                template<class Archive>
                void save(Archive & ar, const unsigned int version) const
                {
                    // note, version is always the latest when saving
                    ar  & driver_name;
                    ar  & stops;
                }
                template<class Archive>
                void load(Archive & ar, const unsigned int version)
                {
                    if(version > 0)
                        ar & driver_name;
                    ar  & stops;
                }
                BOOST_SERIALIZATION_SPLIT_MEMBER()
            public:
                bus_route(){}
            };
             
            BOOST_CLASS_VERSION(bus_route, 1)
             

            BOOST_SERIALIZATION_SPLIT_MEMBER() 宏生成調(diào)用 save 或 load的代碼,依賴于是否檔案被用于“存儲(chǔ)”或“裝載”。

             

            檔案

            我們這里討論將聚焦到類的序列化能力上。被序列化的數(shù)據(jù)的實(shí)際編碼實(shí)現(xiàn)于檔案(archive)類中。被序列化的數(shù)據(jù)流是所選檔案(archive)類的序列化的產(chǎn)物。(鍵)key設(shè)計(jì)決定這兩個(gè)組件的獨(dú)立性。允許任何序列化的規(guī)范可用于任何檔案(archive)。

            在這篇指南中,我們用了一個(gè)檔案類-用于存儲(chǔ)的text_oarchive和用于裝載的text_iarchive類。在庫中其他檔案類的接口完全一致。一旦類的序列化已經(jīng)被定義,類能被序列化到任何檔案類型。

            假如當(dāng)前的檔案集不能提供某個(gè)屬性,格式,或行為需要特化的應(yīng)用。要么創(chuàng)建一個(gè)新的要么從已有的里面衍生一個(gè)。將在后繼文檔中描述。

            注意我們的例子save和load程序數(shù)據(jù)在一個(gè)程序中,這是為了討論方便而已。通常,被裝載的檔案或許在或許不在同一個(gè)程序中。

            T完整的演示程序 - demo.cpp 包括:

            1. 創(chuàng)建各種類別的 stops, routes 和 schedules
            2. 顯示它
            3. 序列化到一個(gè)名叫 "testfile.txt"的文件中
            4. 還原到另一個(gè)結(jié)構(gòu)中
            5. 顯示被存儲(chǔ)的結(jié)構(gòu)

            這個(gè)程序的輸出 分證實(shí)了對序列化系統(tǒng)所有的要求,都在這個(gè)系統(tǒng)中體現(xiàn)了。對序列化文件是ASCII文本的檔案文件的內(nèi)容 能被顯示。

            posted on 2008-10-19 00:38 肥仔 閱讀(2636) 評論(1)  編輯 收藏 引用 所屬分類: Boost & STL

            評論

            # re: Boost Serialization 庫教程  回復(fù)  更多評論   

            使用 febird.dataio,比二進(jìn)制 boost.serialization 快 50 倍
            http://code.google.com/p/febird/
            http://blog.csdn.net/whinah
            2009-04-08 12:42 | rockeet
            香港aa三级久久三级老师2021国产三级精品三级在 | 久久久这里只有精品加勒比| 热久久国产欧美一区二区精品| 久久精品无码av| 色偷偷偷久久伊人大杳蕉| 久久香蕉国产线看观看乱码| 日韩影院久久| 91精品国产9l久久久久| 久久这里有精品| 国产成人久久精品二区三区| 亚洲熟妇无码另类久久久| 99久久综合国产精品二区| 日韩av无码久久精品免费| 久久精品这里只有精99品| 精品无码久久久久国产| 欧美黑人激情性久久| 久久精品国产WWW456C0M| 久久久久人妻精品一区二区三区 | 久久精品国产亚洲AV大全| 久久嫩草影院免费看夜色| 久久久中文字幕| 亚洲精品无码久久久久久| 日韩亚洲国产综合久久久| 丁香五月综合久久激情| 国产精品久久久久久久久| 亚洲国产精品18久久久久久| 99久久国产亚洲综合精品| 日韩影院久久| 国产精品乱码久久久久久软件 | 久久99热这里只有精品国产| 久久强奷乱码老熟女| 国产午夜福利精品久久| 2020最新久久久视精品爱| 99久久免费国产特黄| 99国产欧美精品久久久蜜芽 | 色综合久久久久综合体桃花网| 青青草原综合久久大伊人| 伊人热热久久原色播放www| 伊色综合久久之综合久久| 亚洲国产成人久久一区WWW| 99久久这里只精品国产免费|