boost 序列化2

本文详细展示了如何使用Boost库进行序列化操作,包括内置类型、类类型、指针、数组、STL容器及类的版本控制。通过示例代码解释了如何保存和加载对象到文件,并演示了在类的版本更新时如何处理旧数据的兼容性问题。
摘要由CSDN通过智能技术生成

http://dozb.bokee.com/1692310.html#simplecase

#include<boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <fstream>

const int SIZE = 4;

using namespace std;
// 可序列化的成员
// 一个可序列化的类,可拥有可序列化的成员(普通内置类型成员变量)
class gps_position

{
private:

	friend class boost::serialization::access;
	template<class Archive>
	void serialize(Archive & ar, const unsigned int version)
	{
		ar & degrees;
		ar & minutes;
		ar & seconds;
	}
	int degrees;
	int minutes;
	float seconds;
public:
	gps_position() {};
	gps_position(int d, int m, float s) :
		degrees(d), minutes(m), seconds(s)
	{}
};
/以下等价gps_position
class gps_position1

{
public:
	int degrees;
	int minutes;
	float seconds;
	gps_position1() {};
	gps_position1(int d, int m, float s) :
		degrees(d), minutes(m), seconds(s)
	{}
};
namespace boost {
	namespace serialization {
		template<class Archive>
		void serialize(Archive & ar, gps_position1 & g, const unsigned int version)

		{
			ar & g.degrees;
			ar & g.minutes;
			ar & g.seconds;
		}
	} 

}
/

// 可序列化的成员
// 一个可序列化的类,可拥有可序列化的成员(类类型成员变量)
class bus_stop
{
	friend class boost::serialization::access;
	template<class Archive>
	void serialize(Archive & ar, const unsigned int version)
	{
		// 序列化类成员变量
		ar & latitude;
		ar & longitude;
	}
	gps_position latitude;		// 经度
	gps_position longitude;		// 纬度

public:
	bus_stop() {}
	bus_stop(const gps_position & lat_, const gps_position & long_) :
		latitude(lat_), longitude(long_)
	{}
	virtual ~bus_stop() {}

};
BOOST_SERIALIZATION_ASSUME_ABSTRACT(bus_stop)

// 派生类
// 派生类应包含其基类的序列化
class bus_stop_corner : public bus_stop
{
	friend class boost::serialization::access;
	template<class Archive>
	void serialize(Archive & ar, const unsigned int version)
	{
		// serialize base class information(序列化基类)
		ar & boost::serialization::base_object<bus_stop>(*this);// 注意在派生类中不要直接调用其基类的序列化函数
		ar & street1;
		ar & street2;
	}
	std::string street1;	// 停靠街区1
	std::string street2;	// 停靠街区2
	virtual std::string description() const
	{
		return street1 + " and " + street2;
	}
public:
	bus_stop_corner() {}
	bus_stop_corner(const gps_position & lat_, const gps_position &long_,
		const std::string & s1_, const std::string & s2_
	) :
		bus_stop(lat_, long_), street1(s1_), street2(s2_)
	{}
};

class bus_stop_destination : public bus_stop
{
	friend class boost::serialization::access;
	std::string name;
	virtual std::string description() const
	{
		return name;
	}
	template<class Archive>
	void serialize(Archive &ar, const unsigned int version)
	{
		ar & boost::serialization::base_object<bus_stop>(*this);
		ar & name;
	}
public:

	bus_stop_destination() {}
	bus_stop_destination(
		const gps_position & _lat, const gps_position & _long, const std::string & _name
	) :
		bus_stop(_lat, _long), name(_name)
	{
	}
};

// 指针
class bus_route
{
	friend class boost::serialization::access;
	bus_stop * stops[SIZE];		// 路线
	template<class Archive>
	void serialize(Archive & ar, const unsigned int version)
	{
		int i;
		for (i = 0; i < SIZE; ++i)
		{
			ar & stops[i];
		}
	}
public:
	bus_route() {}
};

// 数组(上述等价的代码)
class bus_route1
{
	friend class boost::serialization::access;
	bus_stop * stops[SIZE];
	template<class Archive>
	void serialize(Archive & ar, const unsigned int version)
	{
		ar & stops;
	}
public:
	bus_route1() {}
};

// STL容器
#include <boost/serialization/list.hpp>
class bus_route2
{
	friend class boost::serialization::access;
	std::list<bus_stop *> stops;	// list版路线
	template<class Archive>
	void serialize(Archive & ar, const unsigned int version)
	{
		ar.register_type(static_cast<bus_stop_corner *>(NULL));			// 序列化bus_stop的派生类对象时需要注册其类型,否则报错
		ar.register_type(static_cast<bus_stop_destination *>(NULL));
		ar & stops;
	}

public:
	void Append(bus_stop* bs)
	{
		stops.push_back(bs);
	}
	bus_route2() {}

};

// 类的版本(如更新上述类,添加一个该路线的司机)
// 这样直接加完会出异常,在读取旧版本所生成的数据文件时。这是version的功能就体现出来了
class bus_route2_1
{
	friend class boost::serialization::access;
	std::string driverName;			// 添加路线司机名
	std::list<bus_stop *> stops;	// list版路线
	template<class Archive>
	void serialize(Archive & ar, const unsigned int version)
	{
		ar & driverName;
		ar & stops;
	}
public:
	bus_route2_1() {}
};

// 修改后的类
#include<boost/serialization/version.hpp>
class bus_route2_2
{
	friend class boost::serialization::access;
	std::list<bus_stop *> stops;
	std::string driverName;
	template<class Archive>
	void serialize(Archive & ar, const unsigned int version)
	{
		// only save/load driver_name for newer archives
		if (version > 0)// version = 1
		{
			ar & driverName;
		}
		ar & stops;

	}
public:
	bus_route2_2() {}
};
BOOST_CLASS_VERSION(bus_route2_2, 1)

// 把serialize拆分成save/load
#include<boost/serialization/split_member.hpp>
class bus_route2_3
{
	friend class boost::serialization::access;
	std::list<bus_stop *> stops;
	std::string driverName;
	template<class Archive>
	void save(Archive & ar, const unsigned int version) const
	{
		// note, version is always the latest when saving
		ar  & driverName;
		ar  & stops;
	}
	template<class Archive>
	void load(Archive & ar, const unsigned int version)
	{
		if (version > 0)
		{
			ar & driverName;
		}
		ar  & stops;
	}
	BOOST_SERIALIZATION_SPLIT_MEMBER()// 宏生成调用 save 或 load的代码,依赖于是否档案被用于“存储”或“装载”。
public:
	bus_route2_3() {}
};
BOOST_CLASS_VERSION(bus_route2_3, 2)

#include <boost/archive/tmpdir.hpp>


// 保存\加载一条路线
void save_bus_route(const bus_route2 &s, const char * filename) {
	std::ofstream ofs(filename);
	boost::archive::text_oarchive oa(ofs);
	oa << s;
}

void load_bus_route(bus_route2 &s, const char * filename)
{
	std::ifstream ifs(filename);
	boost::archive::text_iarchive ia(ifs);

	ia >> s;
}



int main()
{
	{
		std::ofstream ofs("filename");
		boost::archive::text_oarchive oa(ofs);
		const gps_position g(35, 59, 24.567f);
		oa << g;
		ofs.close();
		std::ifstream ifs("filename", std::ios::binary);
		boost::archive::text_iarchive ia(ifs);
		gps_position newg;
		ia >> newg;
		ifs.close();
	}

	{
		std::ofstream ofs("filename1");
		boost::archive::text_oarchive oa(ofs);
		const gps_position1 g(35, 59, 24.567f);
		oa << g;
		ofs.close();
		std::ifstream ifs("filename1", std::ios::binary);
		boost::archive::text_iarchive ia(ifs);
		gps_position1 newg;
		ia >> newg;
		ifs.close();
	}

	// 指针
	{
		bus_stop *bs0 = new bus_stop(
			gps_position(34, 135, 52.560f),
			gps_position(134, 22, 78.30f)
		);
		bus_stop *bs1 = new bus_stop(
			gps_position(35, 137, 23.456f),
			gps_position(133, 35, 54.12f)
		);
		bus_stop *bs2 = new bus_stop_corner(
			gps_position(35, 136, 15.456f),
			gps_position(133, 32, 15.300f),
			"24th Street", "10th Avenue"
		);
		bus_stop *bs3 = new bus_stop_corner(
			gps_position(35, 134, 48.789f),
			gps_position(133, 32, 16.230f),
			"State street", "Cathedral Vista Lane"
		);
		bus_stop *bs4 = new bus_stop_destination(
			gps_position(35, 134, 48.789f),
			gps_position(133, 32, 16.230f),
			"Cathedral Vista Lane11111"
		);
		bus_stop *bs5 = new bus_stop_destination(
			gps_position(35, 134, 48.789f),
			gps_position(133, 32, 16.230f),
			"Cathedral Vista Lane22222"
		);
		


		bus_route2 saveroute,loadsroute;
		saveroute.Append(bs0);
		saveroute.Append(bs1);
		saveroute.Append(bs2);
		saveroute.Append(bs3);
		saveroute.Append(bs4);
		saveroute.Append(bs5);

		std::string filename/*(boost::archive::tmpdir())*/;
		filename += "filename2";
		save_bus_route(saveroute, filename.c_str());
		load_bus_route(loadsroute, filename.c_str());
		delete bs0; bs0 = NULL;
		delete bs1; bs1 = NULL;
		delete bs2; bs2= NULL;
		delete bs3; bs3 = NULL;
		int ac = 1;
	}
	return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值