怎样用boost::serialization去序列化派生模板类(续)

怎样用boost::serialization去序列化派生模板类这篇文章中,介绍了序列化派生类模板类,

在写测试用例时一直出现编译错误,调了很久也没跳出来,今天偶然试了一下...居然调了出来。

先看看变异错误的代码(。。。看不出有错,可是编译就有错)。

基类代码:

class base_class
{
public:
	base_class(int m=0) : base_member_(0) {}
	virtual ~base_class() {}

	virtual void print_data() = 0;

private:
	class boost::serialization::access;//#1
	template<typename Archive>
	void serialize(Archive & ar, const unsigned int file_version)//#2
	{
		ar & BOOST_SERIALIZATION_NVP(base_member_);
		//ar & BOOST_SERIALIZATION_NVP(other member...);
	}

protected:
	int base_member_;
	//other member...
};

按照前面几篇的列子:


#1应该声明为友元类(不知道为什么,看看这篇文章boost::serialization
拆分serialize函数
)。

#2实现一个serialize函数。这应该没问题???????可是却又问题。后面就知

道了。

然后来看看派生模板类的代码:

template<typename T>//#1
class divided_class : public base_class
{
public:
	divided_class(int m = 0, T d = T()) : base_class(m), diveded_member_(d) {}
	virtual ~divided_class() {}

	virtual void print_data()
	{
		std::cout << base_member_ << " "
			<< diveded_member_ << " ";
	}

private:
	class boost::serialization::access;//#2
	template<typename Archive>
	void serialize(Archive& ar, const unsigned int file_version)//#3
	{
		ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_class);
		ar & BOOST_SERIALIZATION_NVP(diveded_member_);
		//ar & BOOST_SERIALIZATION_NVP(other member...);
	}

private:
	T diveded_member_;
	//other member....
};

#1 diveide_class 是一个模板派生类


#2 声明友元类

#3 实现派生类的serialize函数

这样写应该也没问题。

好,接下来写个save()函数测试一下:

void save()
{
	std::ofstream ofs("t8.xml");
	boost::archive::xml_oarchive oa(ofs);

	base_class* int_base = new divided_class<int>(1, 3);
	base_class* str_base = new divided_class<std::string>(1, "wyp");
	base_class* float_base = new divided_class<float>(1, 3.1415926f);

	//Now the tricky point is to register class in serialize
	oa.template register_type<divided_class<int>>(NULL);
	oa.template register_type<divided_class<std::string>>(NULL);
	oa.template register_type<divided_class<float>>(NULL);

	//begin serialize
	oa & BOOST_SERIALIZATION_NVP(int_base);
	oa & BOOST_SERIALIZATION_NVP(str_base);
	oa & BOOST_SERIALIZATION_NVP(float_base);

	//delete pointer ...
}

在main函数中条用这个save函数。

编译器会出现几个错误:

Error	1	error C2248: ‘T88::divided_class<T>::serialize‘ : cannot access private member declared in class ‘T88::divided_class<T>‘	d:\sdk\boost_1_53_0\boost\serialization\access.hpp	118
Error	2	error C2248: ‘T88::divided_class<T>::serialize‘ : cannot access private member declared in class ‘T88::divided_class<T>‘	d:\sdk\boost_1_53_0\boost\serialization\access.hpp	118
...

就是派生类的serialize不能访问私有数据。很诡异!

serialize本来就是派生类的成员函数,而且access类还声明为友元类(access 要调用派生类的serialize)。不知道为什么?求解。。。。。。。

找不出就换了一种方法,上面的serialize函数intrusive式,就换成一种non-intrusive式的,

因为非入侵式的没有this指针:

template<typename Archive>
	void serialize(Archive& ar, const unsigned int file_version)
	{
		ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_class);//#1
		ar & BOOST_SERIALIZATION_NVP(diveded_member_);
		//ar & BOOST_SERIALIZATION_NVP(other member...);
	}

#1这个宏中包含一个this指针,因此这个只能留在类里面,就是定义一个函数条用这个宏:

template<typename Archive>
		void serialize_base_class(Archive& ar)
		{
			ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_class);
		}

然后声明派生模板类的友元函数serialize:

template<typename Archive, typename TT>
	                      friend void serialize(Archive& ar, divided_class<TT>& divcls,                                                      const unsigned int file_version);

接着就是在类的外面实现这个函数:

template<typename Archive, typename T>
void serialize(Archive& ar, divided_class<T>& discls, const unsigned int file_version)
	{
		discls.serialize_base_class(ar);//条用序列化基类的成员函数
		ar & BOOST_SERIALIZATION_NVP(discls.diveded_member_);
		//ar & BOOST_SERIALIZATION_NVP(other member...);
	}

这样应该解决问题了,编译。。。。

果然解决了派生类的问题,可是基类却出现了和派生了一样的问题:

Error	2	error C2248: ‘T88::base_class::serialize‘ : cannot access private member declared in class ‘T88::base_class‘	d:\sdk\boost_1_53_0\boost\serialization\access.hpp	118

只能才去同样的方法来解决:

private:
		/*
		class boost::serialization::access;
		template<typename Archive>
		void serialize(Archive & ar, const unsigned int file_version)
		{
			ar & BOOST_SERIALIZATION_NVP(base_member_);
			//ar & BOOST_SERIALIZATION_NVP(other member...);
		}*
		*/
template<typename Archive>
friend void serialize(Archive& ar, base_class& bascls, const unsigned int file_version);

在类外面:
template<typename Archive>
	void serialize(Archive& ar, base_class& bascls, const unsigned int file_version)
	{
		ar & BOOST_SERIALIZATION_NVP(bascls.base_member_);
		//ar & BOOST_SERIALIZATION_NVP(other member...);
	}

编译运行果然解决问题!

可是现在还是不知道原来的代码有什么错误!

正确的测试列子代码如下:

class base_class
{
public:
	base_class(int m=0) : base_member_(0) {}
	virtual ~base_class() {}

	virtual void print_data() = 0;

private:
	template<typename Archive>
	friend void serialize(Archive& ar, base_class& bascls, const unsigned int file_version);
protected:
	int base_member_;
	//other member...
};

template<typename Archive>
void serialize(Archive& ar, base_class& bascls, const unsigned int file_version)
{
	ar & BOOST_SERIALIZATION_NVP(bascls.base_member_);
	//ar & BOOST_SERIALIZATION_NVP(other member...);
}

template<typename T>
class divided_class : public base_class
{
public:
	divided_class(int m = 0, T d = T()) : base_class(m), diveded_member_(d) {}
	virtual ~divided_class() {}

	virtual void print_data()
	{
		std::cout << base_member_ << " "
			<< diveded_member_ << " ";
	}

private:
	class boost::serialization::access;
	template<typename Archive>
	void serialize_base_class(Archive& ar)
	{
		ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_class);
	}

	template<typename Archive, typename TT>
	friend void serialize(Archive& ar, divided_class<TT>& divcls, const unsigned int file_version);

private:
	T diveded_member_;
	//other member....
};

template<typename Archive, typename T>
void serialize(Archive& ar, divided_class<T>& discls, const unsigned int file_version)
{
	discls.serialize_base_class(ar);
	ar & BOOST_SERIALIZATION_NVP(discls.diveded_member_);
	//ar & BOOST_SERIALIZATION_NVP(other member...);
}

void save()
{
	std::ofstream ofs("t8.xml");
	boost::archive::xml_oarchive oa(ofs);

	base_class* int_base = new divided_class<int>(1, 3);
	base_class* str_base = new divided_class<std::string>(1, "wyp");
	base_class* float_base = new divided_class<float>(1, 3.1415926f);

	//Now the tricky point is to register class in serialize
	oa.template register_type<divided_class<int>>(NULL);
	oa.template register_type<divided_class<std::string>>(NULL);
	oa.template register_type<divided_class<float>>(NULL);

	//begin serialize
	oa & BOOST_SERIALIZATION_NVP(int_base);
	oa & BOOST_SERIALIZATION_NVP(str_base);
	oa & BOOST_SERIALIZATION_NVP(float_base);

	//delete pointer ...
}

错误代码如下(有兴趣的调下。。。。error存档):

class base_class
{
public:
	base_class(int m=0) : base_member_(0) {}
	virtual ~base_class() {}

	virtual void print_data() = 0;

private:
	class boost::serialization::access;
	template<typename Archive>
	void serialize(Archive & ar, const unsigned int file_version)
	{
	ar & BOOST_SERIALIZATION_NVP(base_member_);
	//ar & BOOST_SERIALIZATION_NVP(other member...);
	}

protected:
	int base_member_;
	//other member...
};

template<typename T>
class divided_class : public base_class
{
public:
	divided_class(int m = 0, T d = T()) : base_class(m), diveded_member_(d) {}
	virtual ~divided_class() {}

	virtual void print_data()
	{
		std::cout << base_member_ << " "
			<< diveded_member_ << " ";
	}

private:
	class boost::serialization::access;
	template<typename Archive>
	void serialize(Archive& ar, const unsigned int file_version)
	{
	ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_class);
	ar & BOOST_SERIALIZATION_NVP(diveded_member_);
	//ar & BOOST_SERIALIZATION_NVP(other member...);
	}
private:
	T diveded_member_;
	//other member....
};

void save()
{
	std::ofstream ofs("t8.xml");
	boost::archive::xml_oarchive oa(ofs);

	base_class* int_base = new divided_class<int>(1, 3);
	base_class* str_base = new divided_class<std::string>(1, "wyp");
	base_class* float_base = new divided_class<float>(1, 3.1415926f);

	//Now the tricky point is to register class in serialize
	oa.template register_type<divided_class<int>>(NULL);
	oa.template register_type<divided_class<std::string>>(NULL);
	oa.template register_type<divided_class<float>>(NULL);

	//begin serialize
	oa & BOOST_SERIALIZATION_NVP(int_base);
	oa & BOOST_SERIALIZATION_NVP(str_base);
	oa & BOOST_SERIALIZATION_NVP(float_base);

	//delete pointer ...
}//求大神解决问题。。。。

怎样用boost::serialization去序列化派生模板类(续)

时间: 2024-10-14 04:24:05

怎样用boost::serialization去序列化派生模板类(续)的相关文章

如何用boost::serialization去序列化派生模板类(续)

在 如何用boost::serialization去序列化派生模板类这篇文章中,介绍了序列化派生类模板类, 在写測试用例时一直出现编译错误,调了非常久也没跳出来,今天偶然试了一下...竟然调了出来. 先看看变异错误的代码(...看不出有错,但是编译就有错). 基类代码: class base_class { public: base_class(int m=0) : base_member_(0) {} virtual ~base_class() {} virtual void print_da

怎样用boost::serialization去序列化派生模板类

本篇是boost::serialization 用基类指针转存派生类(错误多多,一波三折)的姊妹篇,这里只不过做一个总结. 先来看一个基类 class base_class { public: base_class(int m=0) : base_member_(0) {} virtual ~base_class() {} virtual void print_data() = 0; protected: int base_member_; //other member... }; 它的一个模板

boost::serialization(2)序列化基类

在派生类中序列化一个基类 假如有一个基类如下: class student_info { public: student_info() {} virtual ~student_info() {} student_info(const std::string& sn, const std::string& snm, const std::string& sg) : name_(sn), number_(snm), grade_(sg) { } virtual void print_i

boost::serialization 用基类指针转存派生类(错误多多,一波三折)

boost::serialization 也支持c++的多态,这样我们就可以通过使用基类的指针来转存派生类, 我们接着上一篇( boost::serialization(2)序列化基类 )的例子来看: 基类和派生类的代码如下: class student_info { public: student_info() {} virtual ~student_info() {} student_info(const std::string& sn, const std::string& snm,

最常用的两种C++序列化方案的使用心得(protobuf和boost serialization)

导读 1. 什么是序列化? 2. 为什么要序列化?好处在哪里? 3. C++对象序列化的四种方法 4. 最常用的两种序列化方案使用心得 正文 1. 什么是序列化? 程序员在编写应用程序的时候往往需要将程序的某些数据存储在内存中,然后将其写入某个文件或是将它传输到网络中的另一台计算机上以实现通讯.这个将 程序数据转化成能被存储并传输的格式的过程被称为"序列化"(Serialization),而它的逆过程则可被称为"反序列化" (Deserialization). 简单

最经常使用的两种C++序列化方案的使用心得(protobuf和boost serialization)

导读 1. 什么是序列化? 2. 为什么要序列化?优点在哪里? 3. C++对象序列化的四种方法 4. 最经常使用的两种序列化方案使用心得 正文 1. 什么是序列化? 程序猿在编写应用程序的时候往往须要将程序的某些数据存储在内存中,然后将其写入某个文件或是将它传输到网络中的还有一台计算机上以实现通讯.这个将程序数据转化成能被存储并传输的格式的过程被称为"序列化"(Serialization),而它的逆过程则可被称为"反序列化"(Deserialization). 简

畅游C++ Boost Serialization 序列化

畅游C++ Boost Serialization 序列化 1.C++ Boost::serialization简介 2.工作环境 3.使用方法 3.1第一个简单的例子 -- Hello World ,将字符串内容归档到文本文件中 #include <iostream> #include <fstream> #include <string> #include <cstdio> #include <boost/archive/text_oarchive

对象序列化之Boost.Serialization

最近在写基于海量点云数据建模程序时,碰到一个效率问题:整个建模过程是管道线方式,这里简单地看作是两步,第一步就是生成所需的数据,第二步即是基于这些生成的数据建模:目前所做的工作就是写第二步,第一步的操作不需要变动,这就造成每次对第二步进行修改(再编译链接后执行)后,重新生成所需数据,而这个生成过程是相当缓慢的,从而给开发调试阶段造成极大的时间浪费. 于是就想到了对象序列化,而对象序列化有好几种方案,常用的有Google Protocol Buffers(protobuf).Boost.Seria

boost::serialization 拆分serialize函数

在前篇 boost::serialization 用基类指针转存派生类(错误多多,一波三折)文中我们都是使用serialize函数来实现序列化,其代码格式如下: private: friend class boost::serialization::access; template<typename Archive> void serialize(Archive& ar, const unsigned int version) { ar & BOOST_SERIALIZATIO