利用Boost库进行序列化
2012-11-27 19:33
405 查看
第一部分: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,又充当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类型的成员函数来对其进行读写操作,从而也能够对其进行序列化。[/code]
-------------------------------------------------------
< 转载请注明:http://blog.csdn.net/icvpr >
相关文章推荐
- Java下利用Jackson进行JSON解析和序列化
- 利用java序列化进行对象深Clone
- Java下利用Jackson进行JSON解析和序列化
- 利用boost库进行字符串与文本处理
- Java下利用Jackson进行JSON解析和序列化示例
- 利用序列化进行文件读写
- Java下利用Jackson进行JSON解析和序列化
- Java下利用Jackson进行JSON解析和序列化
- 利用序列化与反序列化对Java对象进行深度复制
- Java下利用Jackson进行JSON解析和序列化
- C# 利用Newtonsoft.Json进行Json序列化与反序列化
- [JAVA反序列化DEMO]利用RMI进行反序列化一键启动工具
- Java下利用Jackson进行JSON解析和序列化
- 利用 进行Json对象的序列化和反序列化 - RJ - 博客园
- Java下利用Jackson进行JSON解析和序列化,注解应用
- Java下利用Jackson进行JSON解析和序列化
- Java下利用Jackson进行JSON解析和序列化
- Java下利用Jackson进行JSON解析和序列化
- 利用序列化进行深度克隆
- 利用JavaScriptSerializer类 进行Json对象的序列化和反序列化和过滤