利用Boost库进行序列化

来源:互联网 发布:linux中echo的用法 编辑:程序博客网 时间:2024/06/10 06:59

 

第一部分:VS2010+Boost:

    • (一)下载安装Boost库
      • 下载地址:http://www.boost.org/
      • 安装到指定目录下,例如:
        • E:\boost_1_51
    • (二)在VS2010中使用Boost库
      • 配置Boost库
        • 配置include路径
          • Visual Studio -> 项目名称上单击右键 -> 属性 -> 配置属性 -> VC++ 目录 -> Include 目录 -> 点击编辑
            • 填入内容:E:\boost_1_51
        • 配置lib路径
          • Visual Studio -> 项目名称上单击右键 -> 属性 -> 配置属性 -> VC++ 目录 -> Library目录 -> 点击编辑
            • 填入内容:E:\boost_1_51\lib

 

第二部分:序列化

    • 详细的使用说明可以参见Boost官网上的tutorial:
        • http://www.boost.org/doc/libs/1_52_0/libs/serialization/doc/index.html

 

  •  为什么要序列化?

        我们希望能够将类对象的成员变量中的值保存下来,以便下次直接恢复使用。这可以通过序列化来实现,即将这些变量值保持下来,以后需要时直接将保持值恢复到类对象的成员变量中。简言之,通过序列化可以保持对象的状态。

  • 序列化工具:

          通过Boost库,我们可以方便地实现对类对象的序列化。

 
 
 
  • 下面通过三个例子来说明Boost库的三种使用方法(注:不止这三种)。
    • 例1—Intrusion Version
      • 现有一个Person类,声明和定义如下:
        • Person.h
        • class Person {public:Person() ;Person(int _age, std::string _name) ;~Person() ;void addScore(const float _score) ;private:int m_age ;std::string m_name ;std::vector<float> m_score ;};
        • Person.cpp
      • Person::Person(){m_age = 0 ;m_name = "name" ;}Person::~Person(){if (m_score.size() > 0){m_score.clear() ;}}Person::Person(int _age, std::string _name):m_age(_age), m_name(_name){}void Person::addScore(const float _score){m_score.push_back(_score) ;}


      • 序列化后的Person类:
      • Person.h
      • class Person {public:Person() ;Person(int _age, std::string _name) ;~Person() ;void addScore(const float _score) ;private:friend class boost::serialization::access ;template<class Archive>void serialize(Archive & ar, const unsigned int version){ar & m_age ;ar & m_name ;ar & m_score ;}private:int m_age ;std::string m_name ;std::vector<float> m_score ;};

      • 测试程序:
      • Person onePerson(25, "fang") ;onePerson.addScore(95.2f) ;std::ofstream ofs("out.bin", std::ios_base::binary) ;if (ofs.is_open()){boost::archive::binary_oarchive oa(ofs) ;oa << onePerson ;}Person otherPerson ;std::ifstream ifs("out.bin", std::ios_base::binary) ;if (ifs.is_open()){boost::archive::binary_iarchive oa(ifs) ;oa >> otherPerson ;}

    •      
    • 即在Person类中添加如上红色部分代码即可。在serialize()函数中,序列化类成员变量。这里根据自己的需要,可以选择序列化某几个变量,不一定要全部都序列化。
    • 通过例子可以看到,Intrusion Version需要修改原先的类。
    
 
    • 例2——Non Intrusion Version
      • 现有一个Animal类,声明和定义如下:
        • Animal.h
        • class Animal {public:Animal() ;Animal(int _age, std::string _name) ;~Animal() ;void addScore(const float _score) ;public:int m_age ;std::string m_name ;std::vector<float> m_score ;};

        • Animal.cpp 
        • Animal::Animal(){m_age = 0 ;m_name = "name" ;}Animal::~Animal(){if (m_score.size() > 0){m_score.clear() ;}}Animal::Animal(int _age, std::string _name):m_age(_age), m_name(_name){}void Animal::addScore(const float _score){m_score.push_back(_score) ;}

        • 序列化后的Animal类:
        • class Animal {public:Animal() ;Animal(int _age, std::string _name) ;~Animal() ;void addScore(const float _score) ;public:int m_age ;std::string m_name ;std::vector<float> m_score ;};namespace boost{namespace serialization{template<class Archive>void serialize(Archive & ar, Animal & animal, const unsigned int version){ar & animal.m_age ;ar & animal.m_name ;ar & animal.m_score ;}}}


           

        • 测试程序:
        •  

          Animal oneAnimal(25, "dog") ;oneAnimal.addScore(95.2f) ;std::ofstream ofs("outAnimal.bin", std::ios_base::binary) ;if (ofs.is_open()){boost::archive::binary_oarchive oa(ofs) ;oa << oneAnimal ;}Animal otherAnimal ;std::ifstream ifs("outAnimal.bin", std::ios_base::binary) ;if (ifs.is_open()){boost::archive::binary_iarchive oa(ifs) ;oa >> otherAnimal;}


               

      • 该例与例1的不同在于:不需要对原来的类进行修改。但这种用法需要类成员变量时public类型的。
 
    • 例3———Non Intrusion Version
      • 现有一个Plant类,声明和定义如下:
      • Plant.h
      • class Plant {public:Plant() ;Plant(int _age, std::string _name) ;~Plant() ;void addScore(const float _score) ;public:void setScore(const std::vector<float> _scoreVct) ;std::vector<float> getScore() const ; int m_age ;std::string m_name ;private:std::vector<float> m_score ;};
      • Plant.cpp
        Plant::Plant(){m_age = 0 ;m_name = "name" ;}Plant::~Plant(){if (m_score.size() > 0){m_score.clear() ;}}Plant::Plant(int _age, std::string _name):m_age(_age), m_name(_name){}void Plant::addScore(const float _score){m_score.push_back(_score) ;}void Plant::setScore(const std::vector<float> _scoreVct) {m_score = _scoreVct ;}std::vector<float> Plant::getScore() const {return m_score ;}

      • 序列化后的Plant类:
      • Plant.h
      • class Plant {public:Plant() ;Plant(int _age, std::string _name) ;~Plant() ;void addScore(const float _score) ;public:void setScore(const std::vector<float> _scoreVct) ;std::vector<float> getScore() const ; int m_age ;std::string m_name ;private:std::vector<float> m_score ;};// 通过该宏,将序列化分为:load 和 save// 这样的好处在于:load 和 save 两个函数可以编写不同代码// 而前面两个例子中的serialize函数即充当load,又充当saveBOOST_SERIALIZATION_SPLIT_FREE(Plant)namespace boost{namespace serialization{template<class Archive>void save(Archive & ar, const Plant & plant, const unsigned int version){ar & plant.m_age ;ar & plant.m_name ;// 通过公共函数来获取私有成员变量std::vector<float> scores(plant.getScore());  ar & scores ;}template<class Archive>void load(Archive & ar, Plant & plant, const unsigned int version){ar & plant.m_age ;ar & plant.m_name ;// 通过公共函数来设置私有成员变量std::vector<float> scores ;ar & scores ;plant.setScore(scores) ; }}}

      • 测试程序:

                                       

 Plant onePlant(25, "tree") ;onePlant.addScore(95.2f) ;std::ofstream ofs("outPlant.bin", std::ios_base::binary) ;if (ofs.is_open()){boost::archive::binary_oarchive oa(ofs) ;oa << onePlant ;}Plant otherPlant ;std::ifstream ifs("outPlant.bin", std::ios_base::binary) ;if (ifs.is_open()){boost::archive::binary_iarchive oa(ifs) ;oa >> otherPlant;}


 

      • 该例与例2的区别在于:
        •     1)该类的序列化操作被分解为了两个动作:load和save。load和save两个函数内部的操作可以不同,我们可以为其分别编写不同的代码;前面两个例子中的serialize函数即充当了load又充当了save,在序列化时充当的是save的角色,在反序列化时充当的是load的角色。
        •     2)对于不是public类型的成员变量,我们可以通过public类型的成员函数来对其进行读写操作,从而也能够对其进行序列化。





          -------------------------------------------------------
          < 转载请注明:http://blog.csdn.net/icvpr >



原创粉丝点击