您的位置:首页 > 编程语言 > C语言/C++

利用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 >
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Boost库 C++ 序列化