利用Boost库进行序列化

 

第一部分: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 >



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章