第一部分:VS2010+Boost:
- (一)下载安装Boost库
- 下载地址:http://www.boost.org/
- 安装到指定目录下,例如:
- E:\boost_1_51
- (二)在VS2010中使用Boost库
- 配置Boost库
- 配置include路径
- Visual Studio -> 项目名称上单击右键 -> 属性 -> 配置属性 -> VC++ 目录 -> Include 目录 -> 点击编辑
- 填入内容:E:\boost_1_51
- Visual Studio -> 项目名称上单击右键 -> 属性 -> 配置属性 -> VC++ 目录 -> Include 目录 -> 点击编辑
- 配置lib路径
- Visual Studio -> 项目名称上单击右键 -> 属性 -> 配置属性 -> VC++ 目录 -> Library目录 -> 点击编辑
- 填入内容:E:\boost_1_51\lib
- Visual Studio -> 项目名称上单击右键 -> 属性 -> 配置属性 -> VC++ 目录 -> Library目录 -> 点击编辑
- 配置include路径
- 配置Boost库
第二部分:序列化
- 详细的使用说明可以参见Boost官网上的tutorial:
- 为什么要序列化?
我们希望能够将类对象的成员变量中的值保存下来,以便下次直接恢复使用。这可以通过序列化来实现,即将这些变量值保持下来,以后需要时直接将保持值恢复到类对象的成员变量中。简言之,通过序列化可以保持对象的状态。
- 序列化工具:
通过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类,声明和定义如下:
-
-
即在Person类中添加如上红色部分代码即可。在serialize()函数中,序列化类成员变量。这里根据自己的需要,可以选择序列化某几个变量,不一定要全部都序列化。
-
通过例子可以看到,Intrusion Version需要修改原先的类。
- 例1—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 >
-