现在的位置: 首页 > 综合 > 正文

利用Boost库进行序列化

2013年06月04日 ⁄ 综合 ⁄ 共 5176字 ⁄ 字号 评论关闭

 

第一部分:VS2010+Boost:

    • (一)下载安装Boost库

    • (二)在VS2010中使用Boost库
      • 配置Boost库

        • 配置include路径

          • Visual Studio -> 项目名称上单击右键 -> 属性 -> 配置属性 -> VC++ 目录 -> Include 目录 -> 点击编辑

            • 填入内容:E:\boost_1_51
        • 配置lib路径
          • Visual Studio -> 项目名称上单击右键 -> 属性 -> 配置属性 -> VC++ 目录 -> Library目录 -> 点击编辑

            • 填入内容:E:\boost_1_51\lib

 

第二部分:序列化

 

  •  为什么要序列化?

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

  • 序列化工具:

          通过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,又充当save
          BOOST_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 >

    【上篇】
    【下篇】

    作者:

    抱歉!评论已关闭.