原文链接:https://blog.csdn.net/qq2399431200/article/details/45621921

目录

1.工作环境

2.使用方法

3.工程下载

4.总结

5.参考文献

6.更新

7.C++ Boost::serialization简介

内容
1.工作环境

VS2010 C++,Windows 7,Boost _1_55_0

2.使用方法

1.到Boost官网下载对应操作系统平台下的Boost库,此库需要进行编译以生成“静态”和“共享”库。具体编译方法请上网搜索;

2.包含解压后的头文件路径到工程中:VS2010|选择工程|属性|配置属性|VC++目录|

包含目录|添加“D:\C++\Boost\boost_1_55_0”    —— boost库头文件路径

库目录|添加“D:\C++\Boost\boost_1_55_0\stage\lib”  —— boost库.lib或.dll文件路径

2.1第一个简单的例子 —— Hello World ,将字符串内容归档到文本文件中

#include <iostream>
    #include <fstream>
    #include <string>
    #include <cstdio>
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
     
    // 清单1.将字符串保存到文本归档文件中
    void save()
    {
        std::ofstream file("archive.txt");
        boost::archive::text_oarchive oa(file);
        std::string s = "Hello world\n";
        oa << s;  // oa & s; 清单3.使用&运算符执行“转储-恢复”操作
    }
     
    // 清单2.将字符串的内容加载到文本文件中
    void load()
    {
        std::ifstream file("archive.txt");
        boost::archive::text_iarchive ia(file);
        std::string s;
        ia >> s;  // ia & s; 清单3.使用&运算符执行“转储-恢复”操作
        std::cout << s << std::endl;
    }
     
    int main()
    {
        save();
        load();
        getchar();
    }

2.2从xml文档文件执行“转储-恢复”操作

// 清单4
     
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <cstdio>
    #include <boost/archive/xml_iarchive.hpp>
    #include <boost/archive/xml_oarchive.hpp>
     
    void save()
    {
        std::ofstream file("archive.xml");
        boost::archive::xml_oarchive oa(file);
        std::string s = "Hello world! 你好,世界!\n";
        //如果您想使用 XML 归档文件,而不是文本归档文件,需要将数据打包到一个名为 BOOST_SERIALIZATION_NVP 的宏中
        oa & BOOST_SERIALIZATION_NVP(s);  
    }
     
    void load()
    {
        std::ifstream file("archive.xml");
        boost::archive::xml_iarchive ia(file);
        std::string s;
        ia & BOOST_SERIALIZATION_NVP(s);
        std::cout << s << std::endl;
    }
     
    int main()
    {
        save();
        load();
        getchar();
    }

xml归档文件中的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
    <!DOCTYPE boost_serialization>
    <boost_serialization signature="serialization::archive" version="10">
    <s>Hello world! 你好,世界!
    </s>
    </boost_serialization>

2.3对整数数组执行“转储-恢复”操作

// 清单6
     
    #include <fstream>
    #include <iostream>
    #include <algorithm>
    #include <iterator>
    #include <cstdio>
    #include <boost/archive/xml_oarchive.hpp>
    #include <boost/archive/xml_iarchive.hpp>
     
    void save()
    {
        std::ofstream file("archive.xml");
        boost::archive::xml_oarchive oa(file);
        int arrary1[ ] = { 34, 78, 22, 1, 910 };
        oa & BOOST_SERIALIZATION_NVP(arrary1);
    }
     
    /*  是否可以仅通过指定指针 int* restored 完成此操作并为您恢复数组?
    答案是否定的。必须每次都指定大小。如果认真回答此问题的话,答案是对基本
    类型的指针进行序列化非常复杂。*/
    void load()
    {
        std::ifstream file("archive.xml");
        boost::archive::xml_iarchive ia(file);
        int restored[5];  //必须指定数组的大小
        ia & BOOST_SERIALIZATION_NVP(restored);
        std::ostream_iterator<int> oi(std::cout, " ");
        std::copy(restored, restored+5, oi);
    }
     
    int main()
    {
        save();
        load();
        getchar();
    }

xml归档文件中的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
    <!DOCTYPE boost_serialization>
    <boost_serialization signature="serialization::archive" version="10">
    <arrary1>
        <count>5</count>
        <item>34</item>
        <item>78</item>
        <item>22</item>
        <item>1</item>
        <item>910</item>
    </arrary1>
    </boost_serialization>

2.4串行化STL集合

// 清单8
     
    #include <iostream>
    #include <fstream>
    #include <algorithm>
    #include <iterator>
    #include <cstdio>
    #include <boost/archive/xml_iarchive.hpp>
    #include <boost/archive/xml_oarchive.hpp>
    #include <boost/serialization/list.hpp>
    #include <boost/serialization/vector.hpp>
     
    void save( )
    {
        std::ofstream file("archive.xml");
        boost::archive::xml_oarchive oa(file);
        float array[ ] = {34.2, 78.1, 22.221, 1.0, -910.88};
        std::list<float> L1(array, array+5);
        std::vector<float> V1(array, array+5);
        oa & BOOST_SERIALIZATION_NVP(L1);
        oa & BOOST_SERIALIZATION_NVP(V1);
    }
     
    void load()
    {
        std::ifstream file("archive.xml");
        boost::archive::xml_iarchive ia(file);
        std::list<float> L2;
        ia >> BOOST_SERIALIZATION_NVP(L2);  //不需要指定范围/大小
     
        std::vector<float> V2;
        ia >> BOOST_SERIALIZATION_NVP(V2);  //不需要指定范围/大小
     
        std::ostream_iterator<float> oi(std::cout, " ");
        std::copy(L2.begin(), L2.end(), oi );
        std::copy(V2.begin(), V2.end(), oi );
    }
     
    int main()
    {
        save();
        load();
        getchar();
    }

xml归档文件中内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
    <!DOCTYPE boost_serialization>
    <boost_serialization signature="serialization::archive" version="10">
    <L1>
        <count>5</count>
        <item_version>0</item_version>
        <item>34.200001</item>
        <item>78.099998</item>
        <item>22.221001</item>
        <item>1</item>
        <item>-910.88</item>
    </L1>
    <V1>
        <count>5</count>
        <item_version>0</item_version>
        <item>34.200001</item>
        <item>78.099998</item>
        <item>22.221001</item>
        <item>1</item>
        <item>-910.88</item>
    </V1>
    </boost_serialization>

2.5序列化自己的类型——serialize方法的侵入版本

// 清单10 所谓“侵入”即serialize方法写到类中
     
    #include <boost/archive/xml_oarchive.hpp>
    #include <boost/archive/xml_iarchive.hpp>
    #include <iostream>
    #include <fstream>
    #include <cstdio>
     
    namespace
    {
        using std::cout;
        using std::cin;
        using std::endl;
    }
     
    typedef struct date
    {
        unsigned int m_day;
        unsigned int m_month;
        unsigned int m_year;
     
        date(int d, int m, int y):m_day(d), m_month(m) ,m_year(y) {  }
        date( ):m_day(1),m_month(1),m_year(2000) { }
        friend std::ostream& operator << (std::ostream& out, date& d)
        {
            out << "day:" << d.m_day << "month:" << d.m_month << "year:" << d.m_year;
            return out;
        }
        template<typename Archive>
        void serialize(Archive& archive, const unsigned int version)
        {
            archive & BOOST_SERIALIZATION_NVP(m_day);
            archive & BOOST_SERIALIZATION_NVP(m_month);
            archive & BOOST_SERIALIZATION_NVP(m_year);
        }
    }date;
     
    void save( )
    {
        std::ofstream file("archive.xml");
        boost::archive::xml_oarchive oa(file);
        date d(15, 8, 1947);
        oa & BOOST_SERIALIZATION_NVP(d);
    }
     
    void load( )
    {
        std::ifstream file("archive.xml");
        boost::archive::xml_iarchive ia(file);
        date dr;
        ia >> BOOST_SERIALIZATION_NVP(dr);
        std::cout << dr;
    }
     
    int main(void)
    {
        save();
        load();
        getchar();
    }

xml归档文件的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
    <!DOCTYPE boost_serialization>
    <boost_serialization signature="serialization::archive" version="10">
    <d class_id="0" tracking_level="0" version="0">
        <m_day>15</m_day>
        <m_month>8</m_month>
        <m_year>1947</m_year>
    </d>
    </boost_serialization>

2.6序列化自己的类型——serialize方法的非侵入版本

// 清单11 所谓“非侵入”即serialize方法不必写在类中、不属于类
     
    #include <boost/archive/xml_oarchive.hpp>
    #include <boost/archive/xml_iarchive.hpp>
    #include <iostream>
    #include <fstream>
    #include <cstdio>
     
    namespace
    {
        using std::cout;
        using std::cin;
        using std::endl;
    }
     
    typedef struct date
    {
        unsigned int m_day;
        unsigned int m_month;
        unsigned int m_year;
     
        date(int d, int m, int y):m_day(d), m_month(m) ,m_year(y) {  }
        date( ):m_day(1),m_month(1),m_year(2000) { }
        friend std::ostream& operator << (std::ostream& out, date& d)
        {
            out << "day:" << d.m_day << "month:" << d.m_month << "year:" << d.m_year;
            return out;
        }
    }date;
     
    // 序列化相关的类和函数都属于boost::serialization命名空间里,所以自定义的serialize函数也可被其中的其它类和函数调用
    namespace boost
    {
        namespace serialization
        {
            template<typename Archive>
            void serialize(Archive& archive, date& d, const unsigned int version)
            {
                archive & BOOST_SERIALIZATION_NVP(d.m_day);
                archive & BOOST_SERIALIZATION_NVP(d.m_month);
                archive & BOOST_SERIALIZATION_NVP(d.m_year);
            }
        }
    }
     
     
    void save( )
    {
        std::ofstream file("archive.xml");
        boost::archive::xml_oarchive oa(file);
        date d(15, 8, 1947);
        oa & BOOST_SERIALIZATION_NVP(d);
    }
     
    void load( )
    {
        std::ifstream file("archive.xml");
        boost::archive::xml_iarchive ia(file);
        date dr;
        ia >> BOOST_SERIALIZATION_NVP(dr);
        std::cout << dr;
    }
     
    int main(void)
    {
        save();
        load();
        getchar();
    }

2.7通过基类指针转储派生类——使用xml文件归档

// 清单13
     
    #include <boost/archive/xml_oarchive.hpp>
    #include <boost/archive/xml_iarchive.hpp>
    #include <iostream>
    #include <fstream>
    #include <cstdio>
    #include <string>
     
    namespace
    {
        using std::cout;
        using std::cin;
        using std::endl;
        using std::string;
    }
     
    class CBase
    {
        friend class boost::serialization::access;
        template<typename Archive>
        void serialize(Archive& ar, const unsigned int version) { ar & BOOST_SERIALIZATION_NVP(baseName); }
        string baseName;
    public:
        CBase( ) { baseName = "class CBase"; }
        virtual ~CBase( ) { }  //必须加一个virtual函数,否则“dynamic_cast<date*> (dr)”报error C2683: “dynamic_cast”:“CBase”不是多态类型 错误
                              //这是C++多态属性决定的
    };
     
     
    class date : public CBase
    {
        unsigned int m_day;
        unsigned int m_month;
        unsigned int m_year;
    public:
        date(int d, int m, int y):m_day(d), m_month(m) ,m_year(y) {  }
        date( ):m_day(1),m_month(1),m_year(2000) { }
        friend std::ostream& operator << (std::ostream& out, date& d)
        {
            out << "day:" << d.m_day << "\nmonth:" << d.m_month << "\nyear:" << d.m_year;
            return out;
        }
        virtual ~date() { }
    private:
        friend class boost::serialization::access;
        template<typename Archive>
        void serialize(Archive& archive, const unsigned int version)
        {
            //archive & boost::serialization::base_object<CBase> (*this);  //用文本文档归档用此方法,当用于xml归档时会发生error C2664: “boost::mpl::assertion_failed”: 不能将参数 1 从“boost::mpl::failed ************boost::serialization::is_wrapper<T>::* ***********”转换为“boost::mpl::assert<false>::type”
            
                    archive & BOOST_SERIALIZATION_BASE_OBJECT_NVP(CBase);   //用xml归档时,需要将父类对象包装,即用此宏,否则发生如上错误提示
            
                    archive & BOOST_SERIALIZATION_NVP(m_day);
            archive & BOOST_SERIALIZATION_NVP(m_month);
            archive & BOOST_SERIALIZATION_NVP(m_year);
        }
    };
     
    void save( )
    {
        std::ofstream file("archive.xml");
        boost::archive::xml_oarchive oa(file);
        oa.register_type<date>();
        CBase *b = new date(16, 8, 1947);
        oa & BOOST_SERIALIZATION_NVP(b);
        delete b;
    }
     
    void load( )
    {
        std::ifstream file("archive.xml");
        boost::archive::xml_iarchive ia(file);
        ia.register_type<date>();
        CBase *dr;
        ia >> BOOST_SERIALIZATION_NVP(dr);
        date *dr2 = dynamic_cast<date*> (dr);
        std::cout << *dr2;
        delete dr2;
    }
     
    int main(void)
    {
        save();
        getchar();
        load();
        getchar();
    }

xml归档文件的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
    <!DOCTYPE boost_serialization>
    <boost_serialization signature="serialization::archive" version="10">
    <b class_id="0" tracking_level="1" version="0" object_id="_0">
        <CBase class_id="1" tracking_level="1" version="0" object_id="_1">
            <baseName>class CBase</baseName>
        </CBase>
        <m_day>16</m_day>
        <m_month>8</m_month>
        <m_year>1947</m_year>
    </b>
    </boost_serialization>

2.8通过基类指针转储派生类——使用文本文件归档

// 注意和“3.7”的区别
     
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
    #include <iostream>
    #include <fstream>
    #include <cstdio>
    #include <string>
     
    namespace
    {
        using std::cout;
        using std::cin;
        using std::endl;
        using std::string;
    }
     
    class CBase
    {
        friend class boost::serialization::access;
        template<typename Archive>
        void serialize(Archive& ar, const unsigned int version) { ar & baseName; }
        string baseName;
    public:
        CBase( ) { baseName = "class CBase"; }
        virtual ~CBase( ) { }  //必须加一个virtual函数,否则“dynamic_cast<date*> (dr)”报error C2683: “dynamic_cast”:“CBase”不是多态类型 错误
        //这是C++多态属性决定的
    };
     
     
    class date : public CBase
    {
        unsigned int m_day;
        unsigned int m_month;
        unsigned int m_year;
    public:
        date(int d, int m, int y):m_day(d), m_month(m) ,m_year(y) {  }
        date( ):m_day(1),m_month(1),m_year(2000) { }
        friend std::ostream& operator << (std::ostream& out, date& d)
        {
            out << "day:" << d.m_day << "\nmonth:" << d.m_month << "\nyear:" << d.m_year;
            return out;
        }
        virtual ~date() { }
    private:
        friend class boost::serialization::access;
        template<typename Archive>
        void serialize(Archive& archive, const unsigned int version)
        {
            archive & boost::serialization::base_object<CBase> (*this);  //用文本文档归档用此方法,当用于xml归档时会发生error C2664: “boost::mpl::assertion_failed”: 不能将参数 1 从“boost::mpl::failed ************boost::serialization::is_wrapper<T>::* ***********”转换为“boost::mpl::assert<false>::type”
            //archive & BOOST_SERIALIZATION_BASE_OBJECT_NVP(CBase);   //用xml归档时,需要将父类对象包装,即用此宏,否则发生如上错误提示
            archive & m_day;
            archive & m_month;
            archive & m_year;
        }
    };
     
    void save( )
    {
        std::ofstream file("archive.txt");
        boost::archive::text_oarchive oa(file);
        oa.register_type<date>();
        CBase *b = new date(16, 8, 1947);
        oa & b;
        delete b;
    }
     
    void load( )
    {
        std::ifstream file("archive.txt");
        boost::archive::text_iarchive ia(file);
        ia.register_type<date>();
        CBase *dr;
        ia >> dr;
        date *dr2 = dynamic_cast<date*> (dr);
        std::cout << *dr2;
        delete dr2;
    }
     
    int main(void)
    {
        save();
        getchar();
        load();
        getchar();
    }

文本文件归档内容:

22 serialization::archive 10 0 1 0
0 1 0
1 11 class CBase 16 8 1947

2.9使用指针执行“转储-恢复”操作

// 清单15
     
    #include <boost/archive/xml_oarchive.hpp>
    #include <boost/archive/xml_iarchive.hpp>
    #include <iostream>
    #include <fstream>
    #include <cstdio>
     
    namespace
    {
        using std::cout;
        using std::cin;
        using std::endl;
    }
     
    typedef struct date
    {
        unsigned int m_day;
        unsigned int m_month;
        unsigned int m_year;
     
        date(int d, int m, int y):m_day(d), m_month(m) ,m_year(y) {  }
        date( ):m_day(1),m_month(1),m_year(2000) { }
        friend std::ostream& operator << (std::ostream& out, date& d)
        {
            out << "day:" << d.m_day << "month:" << d.m_month << "year:" << d.m_year;
            return out;
        }
        template<typename Archive>
        void serialize(Archive& archive, const unsigned int version)
        {
            archive & BOOST_SERIALIZATION_NVP(m_day);
            archive & BOOST_SERIALIZATION_NVP(m_month);
            archive & BOOST_SERIALIZATION_NVP(m_year);
        }
    }date;
     
    void save( )
    {
        std::ofstream file("archive.xml");
        boost::archive::xml_oarchive oa(file);
        date *d = new date(15, 8, 1947);
        cout << d << endl;
        oa & BOOST_SERIALIZATION_NVP(d);
    }
     
    void load( )
    {
        std::ifstream file("archive.xml");
        boost::archive::xml_iarchive ia(file);
        date *dr;
        ia >> BOOST_SERIALIZATION_NVP(dr);
        std::cout << dr << endl;
        cout << *dr;
    }
     
    int main(void)
    {
        save();
        load();
        getchar();
    }

运行结果:

0047A108
0047A6B8
day:15month:8year:1947

xml归档文件中的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
    <!DOCTYPE boost_serialization>
    <boost_serialization signature="serialization::archive" version="10">
    <d class_id="0" tracking_level="1" version="0" object_id="_0">
        <m_day>15</m_day>
        <m_month>8</m_month>
        <m_year>1947</m_year>
    </d>
    </boost_serialization>

2.10使用指针执行“转储-恢复”操作——将两个指针转储到同一个对象

// 清单17
     
    #include <boost/archive/xml_oarchive.hpp>
    #include <boost/archive/xml_iarchive.hpp>
    #include <iostream>
    #include <fstream>
    #include <cstdio>
     
    namespace
    {
        using std::cout;
        using std::cin;
        using std::endl;
    }
     
    typedef struct date
    {
        unsigned int m_day;
        unsigned int m_month;
        unsigned int m_year;
     
        date(int d, int m, int y):m_day(d), m_month(m) ,m_year(y) {  }
        date( ):m_day(1),m_month(1),m_year(2000) { }
        friend std::ostream& operator << (std::ostream& out, date& d)
        {
            out << "day:" << d.m_day << "month:" << d.m_month << "year:" << d.m_year;
            return out;
        }
        template<typename Archive>
        void serialize(Archive& archive, const unsigned int version)
        {
            archive & BOOST_SERIALIZATION_NVP(m_day);
            archive & BOOST_SERIALIZATION_NVP(m_month);
            archive & BOOST_SERIALIZATION_NVP(m_year);
        }
    }date;
     
    void save()
    {
        std::ofstream file("archive.xml");
        boost::archive::xml_oarchive oa(file);
        date *d = new date(15,8,1947);
        cout << d << endl;
        oa & BOOST_SERIALIZATION_NVP(d);
        date *d2 = d;
        oa & BOOST_SERIALIZATION_NVP(d2);
    }
     
    void load()
    {
        std::ifstream file("archive.xml");
        boost::archive::xml_iarchive ia(file);
        date *dr;
        ia >> BOOST_SERIALIZATION_NVP(dr);
        cout << dr << endl;
        cout << *dr << endl;
        date *dr2;
        ia >> BOOST_SERIALIZATION_NVP(dr2);
        cout << dr2 << endl;
        cout << *dr2;
    }
     
    int main(void)
    {
        save();
        load();
        getchar();
    }

运行结果:

0010A108
0010A6B8
day:15month:8year:1947
0010A6B8
day:15month:8year:1947

xml归档文件中的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
    <!DOCTYPE boost_serialization>
    <boost_serialization signature="serialization::archive" version="10">
    <d class_id="0" tracking_level="1" version="0" object_id="_0">
        <m_day>15</m_day>
        <m_month>8</m_month>
        <m_year>1947</m_year>
    </d>
    <d2 class_id_reference="0" object_id_reference="_0"></d2>
    </boost_serialization>

2.11包含作为d的引用d2的归档文件

// 清单19  和参考网页(IBM)中的那部分不一致
     
    #include <boost/archive/xml_oarchive.hpp>
    #include <boost/archive/xml_iarchive.hpp>
    #include <iostream>
    #include <fstream>
    #include <cstdio>
     
    namespace
    {
        using std::cout;
        using std::cin;
        using std::endl;
    }
     
    typedef struct date
    {
        unsigned int m_day;
        unsigned int m_month;
        unsigned int m_year;
     
        date(int d, int m, int y):m_day(d), m_month(m) ,m_year(y) {  }
        date( ):m_day(1),m_month(1),m_year(2000) { }
        friend std::ostream& operator << (std::ostream& out, date& d)
        {
            out << "day:" << d.m_day << "month:" << d.m_month << "year:" << d.m_year;
            return out;
        }
        template<typename Archive>
        void serialize(Archive& archive, const unsigned int version)
        {
            archive & BOOST_SERIALIZATION_NVP(m_day);
            archive & BOOST_SERIALIZATION_NVP(m_month);
            archive & BOOST_SERIALIZATION_NVP(m_year);
        }
    }date;
     
    void save()
    {
        std::ofstream file("archive.xml");
        boost::archive::xml_oarchive oa(file);
        date *d = new date(15,8,1947);
        cout << d << endl;
        oa & BOOST_SERIALIZATION_NVP(d);
        date* &d2 = d;     //d2 reference d
        oa & BOOST_SERIALIZATION_NVP(d2);  
    }
     
    void load()
    {
        std::ifstream file("archive.xml");
        boost::archive::xml_iarchive ia(file);
        date *dr;
        ia >> BOOST_SERIALIZATION_NVP(dr);
        cout << dr << endl;
        cout << *dr << endl;
        date *dr2;
        ia >> BOOST_SERIALIZATION_NVP(dr2);
        cout << dr2 << endl;
        cout << *dr2;
    }
     
    int main(void)
    {
        save();
        load();
        getchar();
    }

xml归档文件的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
    <!DOCTYPE boost_serialization>
    <boost_serialization signature="serialization::archive" version="10">
    <d class_id="0" tracking_level="1" version="0" object_id="_0">
        <m_day>15</m_day>
        <m_month>8</m_month>
        <m_year>1947</m_year>
    </d>
    <d2 class_id_reference="0" object_id_reference="_0"></d2>
    </boost_serialization>

2.12将serialize拆分成save和load

有时候,您不想使用同样的 serialize 方法来转储和恢复对象。在这种情况下,您可以将 serialize 方法拆分成两个方法,即save 和load,它们具有类似的签名。这两个方法都是之前定义的serialize 方法的一部分。此外,需要添加BOOST_SERIALIZATION_SPLIT_MEMBER 宏作为类定义的一部分。(引用参考文献[1])

// 清单21
     
    #include <boost/archive/xml_oarchive.hpp>
    #include <boost/archive/xml_iarchive.hpp>
    #include <iostream>
    #include <fstream>
    #include <cstdio>
     
    namespace
    {
        using std::cout;
        using std::cin;
        using std::endl;
    }
     
    typedef struct date
    {
        unsigned int m_day;
        unsigned int m_month;
        unsigned int m_year;
     
        date(int d, int m, int y):m_day(d), m_month(m) ,m_year(y) {  }
        date( ):m_day(1),m_month(1),m_year(2000) { }
        friend std::ostream& operator << (std::ostream& out, date& d)
        {
            out << "day:" << d.m_day << "month:" << d.m_month << "year:" << d.m_year;
            return out;
        }
    //     template<typename Archive>
    //     void serialize(Archive& archive, const unsigned int version)
    //     {
    //         archive & BOOST_SERIALIZATION_NVP(m_day);
    //         archive & BOOST_SERIALIZATION_NVP(m_month);
    //         archive & BOOST_SERIALIZATION_NVP(m_year);
    //     }
            //将serialize函数分割成save和load函数,两个者实现的效果是等价的
        template<class Archive>
        void save(Archive& archive, const unsigned int version) const //注意 save 方法签名后的 const。如果没有 const 限定符,该代码将无法编译
        {
            archive << BOOST_SERIALIZATION_NVP(m_day);
            archive << BOOST_SERIALIZATION_NVP(m_month);
            archive << BOOST_SERIALIZATION_NVP(m_year);
        }
     
        template<class Archive>
        void load(Archive& archive, const unsigned int version)
        {
            archive >> BOOST_SERIALIZATION_NVP(m_day);
            archive >> BOOST_SERIALIZATION_NVP(m_month);
            archive >> BOOST_SERIALIZATION_NVP(m_year);
        }
        BOOST_SERIALIZATION_SPLIT_MEMBER( ) // must be part of class
    }date;
     
    void save( )
    {
        std::ofstream file("archive.xml");
        boost::archive::xml_oarchive oa(file);
        date d(15, 8, 1991);
        oa & BOOST_SERIALIZATION_NVP(d);
    }
     
    void load( )
    {
        std::ifstream file("archive.xml");
        boost::archive::xml_iarchive ia(file);
        date dr;
        ia >> BOOST_SERIALIZATION_NVP(dr);
        std::cout << dr;
    }
     
    int main(void)
    {
        save();
        load();
        getchar();
    }

2.13了解Boost::serialize的版本控制

serialize、save 和 load 的方法签名都使用无符号整数版本作为最后一个参数。这些数字有什么用?随着时间变化,类的内部变量名称可能发生变化,添加新的字段或移除已有字段,等等。这是软件开发过程中的自然进程,除了归档文件仍然保存着关于数据类型原有状态的信息。为了规避这个问题,需要使用版本号。(引用参考文献[1])

在date类的基础上增加一个unsigned int  ver变量用于保存当前类Mydate的版本号。

// 清单22
     
    #include <boost/archive/xml_oarchive.hpp>
    #include <boost/archive/xml_iarchive.hpp>
    #include <iostream>
    #include <fstream>
    #include <cstdio>
     
    namespace
    {
        using std::cout;
        using std::cin;
        using std::endl;
    }
     
    typedef struct date
    {
        unsigned int m_day;
        unsigned int m_month;
        unsigned int m_year;
     
        date(int d, int m, int y):m_day(d), m_month(m) ,m_year(y) {  }
        date( ):m_day(1),m_month(1),m_year(2000) { }
        friend std::ostream& operator << (std::ostream& out, date& d)
        {
            out << "day:" << d.m_day << "month:" << d.m_month << "year:" << d.m_year << endl;
            return out;
        }
        template<typename Archive>
        void serialize(Archive& archive, const unsigned int version)
        {
            archive & BOOST_SERIALIZATION_NVP(m_day);
            archive & BOOST_SERIALIZATION_NVP(m_month);
            archive & BOOST_SERIALIZATION_NVP(m_year);
        }
    }date;
    BOOST_CLASS_VERSION(date,0);
     
    // Mydate
    typedef struct Mydate
    {
        unsigned int m_day;
        unsigned int m_month;
        unsigned int m_year;
        unsigned int ver;  //版本
     
        Mydate(int d, int m, int y, int version):m_day(d), m_month(m) ,m_year(y), ver(version) {  }
        Mydate( ):m_day(1),m_month(1),m_year(2000),ver(1) { }
        friend std::ostream& operator << (std::ostream& out, Mydate& d)
        {
            out << "day:" << d.m_day << "month:" << d.m_month << "year:" << d.m_year << " -- Version:" << d.ver << endl;
            return out;
        }
        template<typename Archive>
        void serialize(Archive& archive, const unsigned int version)
        {
            archive & BOOST_SERIALIZATION_NVP(m_day);
            archive & BOOST_SERIALIZATION_NVP(m_month);
            archive & BOOST_SERIALIZATION_NVP(m_year);
            if(version == 1)
            {
                archive & BOOST_SERIALIZATION_NVP(ver);
            }
        }
    }Mydate;
    BOOST_CLASS_VERSION(Mydate,1);
     
    void save( )
    {
        std::ofstream file("version.xml");
        boost::archive::xml_oarchive oa(file);
        date d(15, 8, 1947);
        oa & BOOST_SERIALIZATION_NVP(d);
        Mydate myd(1, 1, 1991, 1);
        oa & BOOST_SERIALIZATION_NVP(myd);
    }
     
    void load( )
    {
        std::ifstream file("version.xml");
        boost::archive::xml_iarchive ia(file);
        date dr;
        ia >> BOOST_SERIALIZATION_NVP(dr);
        Mydate myd;
        ia >> BOOST_SERIALIZATION_NVP(myd);
        std::cout << dr;
        std::cout << myd;
    }
     
    int main(void)
    {
        save();
        load();
        getchar();
    }

运行结果:

day:15month:8year:1947
day:1month:1year:1991 -- Version:1

xml归档文件中内容

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
    <!DOCTYPE boost_serialization>
    <boost_serialization signature="serialization::archive" version="10">
    <d class_id="0" tracking_level="0" version="0">
        <m_day>15</m_day>
        <m_month>8</m_month>
        <m_year>1947</m_year>
    </d>
    <myd class_id="1" tracking_level="0" version="1">
        <m_day>1</m_day>
        <m_month>1</m_month>
        <m_year>1991</m_year>
        <ver>1</ver>
    </myd>
    </boost_serialization>

2.14 使用共享指针boost::shared_ptr执行“转储-恢复”操作

// 清单23
     
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <cstdio>
    #include <boost/archive/xml_iarchive.hpp>
    #include <boost/archive/xml_oarchive.hpp>
    #include <boost/serialization/shared_ptr.hpp>  //缺此头文件 —— error C2039: “serialize”: 不是“boost::shared_ptr<T>”的成员    d:\c++\boost\boost_1_55_0\boost\serialization\access.hpp
     
     
    typedef struct date
    {
        unsigned int m_day;
        unsigned int m_month;
        unsigned int m_year;
     
        date(int d, int m, int y):m_day(d), m_month(m) ,m_year(y) {  }
        date( ):m_day(1),m_month(1),m_year(2000) { }
        friend std::ostream& operator << (std::ostream& out, date& d)
        {
            out << "day:" << d.m_day << "month:" << d.m_month << "year:" << d.m_year;
            return out;
        }
        template<typename Archive>
        void serialize(Archive& archive, const unsigned int version)
        {
            archive & BOOST_SERIALIZATION_NVP(m_day);
            archive & BOOST_SERIALIZATION_NVP(m_month);
            archive & BOOST_SERIALIZATION_NVP(m_year);
        }
    }date;
     
    void save()
    {
        std::ofstream file("shared_ptr.xml");
        boost::archive::xml_oarchive oa(file);
        boost::shared_ptr<date> d (new date(15, 8, 1947));
        oa & BOOST_SERIALIZATION_NVP(d);
        // other code bellow
    }
     
    void load()
    {
        std::fstream file("shared_ptr.xml");
        boost::archive::xml_iarchive ia(file);
        boost::shared_ptr<date> dr;
        ia & BOOST_SERIALIZATION_NVP(dr);
        std::cout << *dr;
    }
     
    int main( )
    {
        save();
        load();
        getchar();
    }

xml文档中的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
    <!DOCTYPE boost_serialization>
    <boost_serialization signature="serialization::archive" version="10">
    <d class_id="0" tracking_level="0" version="1">
        <px class_id="1" tracking_level="1" version="0" object_id="_0">
            <m_day>15</m_day>
            <m_month>8</m_month>
            <m_year>1947</m_year>
        </px>
    </d>
    </boost_serialization>

2.15 指向栈对象的指针需要在实际对象之后转储

// 清单24
     
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <cstdio>
    #include <boost/archive/xml_iarchive.hpp>
    #include <boost/archive/xml_oarchive.hpp>
    #include <boost/serialization/shared_ptr.hpp>  //缺此头文件 —— error C2039: “serialize”: 不是“boost::shared_ptr<T>”的成员    d:\c++\boost\boost_1_55_0\boost\serialization\access.hpp
     
     
    typedef struct date
    {
        unsigned int m_day;
        unsigned int m_month;
        unsigned int m_year;
     
        date(int d, int m, int y):m_day(d), m_month(m) ,m_year(y) {  }
        date( ):m_day(1),m_month(1),m_year(2000) { }
        friend std::ostream& operator << (std::ostream& out, date& d)
        {
            out << "day:" << d.m_day << "month:" << d.m_month << "year:" << d.m_year;
            return out;
        }
        template<typename Archive>
        void serialize(Archive& archive, const unsigned int version)
        {
            archive & BOOST_SERIALIZATION_NVP(m_day);
            archive & BOOST_SERIALIZATION_NVP(m_month);
            archive & BOOST_SERIALIZATION_NVP(m_year);
        }
    }date;
     
    void save()
    {
        std::ofstream file("stackobject.xml");
        boost::archive::xml_oarchive oa(file);
        date d(1,1,1991);
        date *d2 = &d;
        oa & BOOST_SERIALIZATION_NVP(d);  
        oa & BOOST_SERIALIZATION_NVP(d2);  //指向栈对象的指针需要在实际对象之后转储
    }
     
    void load()
    {
        std::fstream file("stackobject.xml");
        boost::archive::xml_iarchive ia(file);
        date dr;
        ia & BOOST_SERIALIZATION_NVP(dr);
        std::cout << dr << std::endl;
        date *dr2;
        ia & BOOST_SERIALIZATION_NVP(dr2);
        std::cout << *dr2 << std::endl;
    }
     
    int main( )
    {
        save();
        load();
        getchar();
    }

xml文档中的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
    <!DOCTYPE boost_serialization>
    <boost_serialization signature="serialization::archive" version="10">
    <d class_id="0" tracking_level="1" version="0" object_id="_0">
    <m_day>1</m_day>
    <m_month>1</m_month>
    <m_year>1991</m_year>
    </d>
    <d2 class_id_reference="0" object_id_reference="_0"></d2>
    </boost_serialization>

如果有多个指针指向同一个对象,Serialization 会使用 class_id_reference 将指针与原对象关联起来(每个对象都有一个唯一的类 ID)。原对象的每个后续指针都会将 object_id_reference 改成 _1、_2,以此类推。

3.工程下载

整个工程的下载地址,点此处。

4.总结

5.参考文献

[1]. 《Boost Serialization 库》 http://www.ibm.com/developerworks/cn/aix/library/au-boostserialization/

6.更新

2015-05-10  第一次更新   全文开始,增加2.1~2.7 部分内容

2015-05-11  第二次更新    增加2.8~2.13部分内容

2015-05-14  第三次更新    增加2.14~2.15部分内容

2015-05-19  第四次更新    提供工程下载

7.C++ Boost::serialization简介

以下内容引用Boost库的“libs/serialization/doc/index.html”页面:

Here, we use the term "serialization" to meanthe reversible deconstruction of an arbitrary set of C++ data structuresto a sequence of bytes. Such a system can be used to reconstitutean equivalent structure in another program context. Depending onthe context, this might used implement object persistence, remoteparameter passing or other facility. In this system we use the term"archive" to refer to a specific rendering of thisstream of bytes. This could be a file of binary data, text data, XML, or some other created by the user of this library.
Our goals for such a system are:

Code portability - depend only on ANSI C++ facilities.
    Code economy - exploit features of C++ such as RTTI, templates, and multiple inheritance, etc. where appropriate to make code shorter and simpler to use.
    Independent versioning for each class definition. That is, when a class definition changed, older files can still be imported to the new version of the class.
    Deep pointer save and restore. That is, save and restore of pointers saves and restores the data pointed to.
    Proper restoration of pointers to shared data.
    Serialization of STL containers and other commonly used templates.
    Data Portability - Streams of bytes created on one platform should be readable on any other.
    Orthogonal specification of class serialization and archive format. That is, any file format should be able to store serialization of any arbitrary set of C++ data structures without having to alter the serialization of any class.
    Non-intrusive. Permit serialization to be applied to unaltered classes. That is, don't require that classes to be serialized be derived from a specific base class or implement specified member functions. This is necessary to easily permit serialization to be applied to classes from class libraries that we cannot or don't want to have to alter.
    The archive interface must be simple enough to easily permit creation of a new type of archive.
    The archive interface must be rich enough to permit the creation of anarchive that presents serialized data as XML in a useful manner.

Other implementations
Before getting started I searched around for current implementations. I found several.

MFC This is the one that I am very familiar with. I have used it for several years and have found it very useful. However it fails requirements 1, 2, 3, 6, 7, and 9. In spite of all the requirements not fulfilled, this is the most useful implementation I've found. It turns out that class versioning - partially implemented in MFC - really is indispensable for my applications. Inevitably, version 1.x of a shipping program needs to store more information in files than was originally provided for. MFC is the only one of these implementations that supports this - though only for the most derived class. Still it's better than nothing and does the job. MFC doesn't implement serialization of STL collections. Though it does so for MFC collections.
    CommonC++ libraries [1] As far as I can tell, this closely follows the MFC implementation but does address a few of the issues. It is portable and creates portable archives but skips versioning. It does support proper and complete restoration of pointers and STL collections. It does address compression though not in the way that I would prefer. The package would also benefit from having better documentation. So it fails to address 2, 3, 7, 8, and 9.
    Eternity [2] This is a bare bones package. It seems well coded but it really needs documentation and examples. It's not obvious how to use it without time consuming study of the source code. Recent versions do support files in XML format. This Fails 3, 6, 7?, 8, and 9.
    Holub's implementation [3] This is the article that first got me thinking about my own requirements for a serialization implementation. Interesting and worth the read if you can overlook the arrogant tone of the prose. This implementation fails 2, 3, 4, 5, and 6.
    s11n [13] This library has similar goals to this one. Some aspects of the implemenation are also similar. As of this writing, it would seem that:
        Portability(1) is guarenteed only for recent versions of GCC.
        Versioning(3) of class definitions is not explicitly supported by the library.
        it doesn't seem to automatically account for shared pointers(5). I concluded this from the documentation as well as the statement that serialization of graph like structures is not supported.
    Its has lots of differences - and lots in common with this implementation.

畅游C++ Boost Serialization 序列化相关推荐

  1. C++使用boost.serialization序列化与反序列化

    我们不再介绍如何安装boost环境,默认已经安装好了 侵入式序列化 #include <fstream> #include <iostream> #include <bo ...

  2. 最常用的两种C++序列化方案的使用心得(protobuf和boost serialization)

    From: http://www.cnblogs.com/lanxuezaipiao/p/3703988.html 导读 1. 什么是序列化? 2. 为什么要序列化?好处在哪里? 3. C++对象序列 ...

  3. boost::serialization模块实现测试 shared_ptr 序列化的测试程序

    boost::serialization模块实现测试 shared_ptr 序列化的测试程序 实现功能 C++实现代码 实现功能 boost::serialization模块实现测试 shared_p ...

  4. boost::serialization模块测试 auto_ptr 序列化的测试程序

    boost::serialization模块测试 auto_ptr 序列化的测试程序 实现功能 C++实现代码 实现功能 boost::serialization模块测试 auto_ptr 序列化的测 ...

  5. Boost Serialization 库(一个有效的调试工具)

    使用了 Boost Serialization 的 Hello World 在执行更重要的任务之前,我们先来验证一下概念.在以下的 清单 1 中,您会看到一个字符串,它的值被转储到一个归档文件中.在以 ...

  6. boost::serialization模块测试extended_type_info的实现,使用多个共享库时有效

    boost::serialization模块测试extended_type_info的实现,使用多个共享库时有效 实现功能 C++实现代码 实现功能 boost::serialization模块测试e ...

  7. boost::serialization模块实现快速二进制归档的测试程序

    boost::serialization模块实现快速二进制归档的测试程序 实现功能 C++实现代码 实现功能 boost::serialization模块实现快速二进制归档的测试程序 C++实现代码 ...

  8. boost::serialization模块指针反序列化的安全异常处理示例

    boost::serialization模块指针反序列化的安全异常处理示例 实现功能 C++实现代码 实现功能 boost::serialization模块指针反序列化的安全异常处理示例 C++实现代 ...

  9. boost::serialization相关的测试程序

    boost::serialization相关的测试程序 实现功能 C++实现代码 实现功能 boost::serialization相关的测试程序 C++实现代码 #include <boost ...

最新文章

  1. Cookies工作原理
  2. MVC匿名类传值学习
  3. 简明python教程购买-自学Python买什么书?
  4. 互联网医疗上市“大逃杀”
  5. asp.net 跨页面传值(一)
  6. 《C语言深度解剖》学习笔记之内存管理
  7. vb未找到方法或数据成员_答疑 | VB首行的Option Explicit有何作用?
  8. 一个基于typescript、mobx、react16、react-router4、antd的后台模板
  9. exp导出excel oracle_OracleToExcel_Oracle导出excel数据(OracleToExcel)下载 v3.1 官方版 - 121下载站...
  10. spring实现定时任务的两种方式
  11. 真核有参转录组测序标准分析-3
  12. H.264/H.265/H.266三代视频编码的图像划分
  13. 全球及中国塑料机械行业十四五发展战略与竞争格局展望报告2022版
  14. 用Photoshop制作LOMO风格暗角效果照片
  15. mysql启动错误1455_orcl-1455错误
  16. iOS生态链寄生数百万开发者:艰难求生面临决择
  17. Autodesk Maya软件介绍
  18. 复现 MMDetection
  19. 【Matlab】在Matlab中输入希腊字母
  20. teamview更换Id

热门文章

  1. Android系统10 RK3399 init进程启动(三十四) 常见Property属性
  2. 手机到底该怎么充电?想不到和之前自己了解的都不一样,涨知识了
  3. java定义数组长度_在JAVA中定义数组时,可不可以一开始不设定数组的长度?
  4. C语言的关键字及其部分关键词详细用法
  5. python毕业设计作品基于django框架外卖点餐系统毕设成品(4)开题报告
  6. Eclipse版本和JDK版本对应关系
  7. 共享购(嗨购):研究建立绿色消费积分制
  8. matlab 计算逆时针夹角,求取向量A逆时针到向量B的夹角
  9. 电脑软件可以上网,但是浏览器网页打不开显示代理服务器配置出错
  10. Microsoft .NET Framework 4.5.1 无法安装(Win7无法访问Windows Installer服务的解决方法)