利用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 >



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