boost::serialization 用基类指针转存派生类(错误多多,一波三折)
来源:互联网 发布:手机会计软件哪个好 编辑:程序博客网 时间:2024/05/17 01:13
boost::serialization 也支持c++的多态,这样我们就可以通过使用基类的指针来转存派生类,
我们接着上一篇(
下面我们来看怎么使用基类的指针转存派生类:
save的代码:
#2:这个代码和以前的一样,还是用一个宏来包装指针。
#2:load的时候也需要宏来包装
#3:这个大家都熟悉
结果抛出异常:boost::archive::archive_exception at memory location 0x0017eb30...
google了一下,下面链接给出了一个解决方法
http://stackoverflow.com/questions/1332602/how-to-serialize-derived-template-classes-with-boost-serialize
大概分为3个步骤:
步骤1:BOOST_SERIALIZATION_ASSUME_ABSTRACT(className),用这个宏来告诉boost className是一个抽象类
步骤2:在save操作中注册派生类:oa.template register_type<middle_student>(NULL),
一定要在oa << BOOST_SERIALIZATION_NVP(sdinfo)之前注册。
步骤3:在load操作中注册派生了:ia.template register_type<middle_student>(NULL)
一定要在ia >> BOOST_SERIALIZATION_NVP(sdinfo)之前注册。
修改后的代码如下:
我们接着上一篇(
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_info() const{std::cout << name_ << " " << number_ << " " << grade_ << std::endl;}private:friend class boost::serialization::access;template<typename Archive>void serialize(Archive& ar, const unsigned int version){ar & BOOST_SERIALIZATION_NVP(name_);ar & BOOST_SERIALIZATION_NVP(number_);ar & BOOST_SERIALIZATION_NVP(grade_);}private:std::string name_;std::string number_;std::string grade_;};class middle_student : public student_info{public:middle_student() {}virtual ~middle_student() {}middle_student(const std::string& sn, const std::string& snm, const std::string& sg, int age): student_info(sn, snm, sg), age_(age){}virtual void print_info(){student_info::print_info();std::cout << age_ << std::endl;}private:friend class boost::serialization::access;template<typename Archive>void serialize(Archive& ar, const unsigned int version){ar & boost::serialization::base_object<student_info>(*this);ar & BOOST_SERIALIZATION_NVP(age_);}private:int age_;};在派生类中使用了基类的基类的序列化: ar & boost::serialization::base_object<student_info>(*this);
下面我们来看怎么使用基类的指针转存派生类:
save的代码:
void save(){std::ofstream ofs("t7.xml");boost::archive::xml_oarchive oa(ofs);student_info* sdinfo = new middle_student("wyp", "0099", "1", 15);//#1oa << BOOST_SERIALIZATION_NVP(sdinfo);//#2std::cout << "xxxx" << std::endl;delete sdinfo;}#1:用一个基类的指针指向了一个用new申请的派生类的指针,很简单,都知道这就是c++的多态。
#2:这个代码和以前的一样,还是用一个宏来包装指针。
load的代码:
void load(){std::ifstream ifs("t7.xml");boost::archive::xml_iarchive ia(ifs);student_info* sdinfo = NULL;//#1ia >> BOOST_SERIALIZATION_NVP(sdinfo);//#2middle_student* mds = dynamic_cast<middle_student*>(sdinfo);//#3mds->print_info();}#1:基类的指针
#2:load的时候也需要宏来包装
#3:这个大家都熟悉
测试代码:
void fun(){save();load();}编译运行!。。。。。。。
结果抛出异常:boost::archive::archive_exception at memory location 0x0017eb30...
google了一下,下面链接给出了一个解决方法
http://stackoverflow.com/questions/1332602/how-to-serialize-derived-template-classes-with-boost-serialize
大概分为3个步骤:
步骤1:BOOST_SERIALIZATION_ASSUME_ABSTRACT(className),用这个宏来告诉boost className是一个抽象类
步骤2:在save操作中注册派生类:oa.template register_type<middle_student>(NULL),
一定要在oa << BOOST_SERIALIZATION_NVP(sdinfo)之前注册。
步骤3:在load操作中注册派生了:ia.template register_type<middle_student>(NULL)
一定要在ia >> BOOST_SERIALIZATION_NVP(sdinfo)之前注册。
修改后的代码如下:
void save(){std::ofstream ofs("t7.xml");boost::archive::xml_oarchive oa(ofs);oa.template register_type<middle_student>(NULL);student_info* sdinfo = new middle_student("wyp", "0099", "1", 15);oa << BOOST_SERIALIZATION_NVP(sdinfo);delete sdinfo;}void load(){std::ifstream ifs("t7.xml");boost::archive::xml_iarchive ia(ifs);ia.template register_type<middle_student>(NULL);student_info* sdinfo = NULL;ia >> BOOST_SERIALIZATION_NVP(sdinfo);middle_student* mds = dynamic_cast<middle_student*>(sdinfo);mds->print_info();}好这下应改没有异常了吧。
结果编译就出错了!!!
错误在这个函数里面
// Anything not an attribute and not a name-value pair is an // error and should be trapped here. template<class T> void save_override(T & t, BOOST_PFTO int) { // If your program fails to compile here, its most likely due to // not specifying an nvp wrapper around the variable to // be serialized. BOOST_MPL_ASSERT((serialization::is_wrapper< T >)); this->detail_common_oarchive::save_override(t, 0); }看注释就知道了,序列化时存在有些数据没有包装,就是没有用那个宏。
就仔细看一下序列化的代码发现这段代码中有一个没用宏来包装:
private:friend class boost::serialization::access;template<typename Archive>void serialize(Archive& ar, const unsigned int version){ar & boost::serialization::base_object<student_info>(*this);//here!!!!!!!!!!!ar & BOOST_SERIALIZATION_NVP(age_);}在调用基类的序列化时没用宏包装
修改如下:
private:friend class boost::serialization::access;template<typename Archive>void serialize(Archive& ar, const unsigned int version){//ar & boost::serialization::base_object<student_info>(*this);ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(student_info);ar & BOOST_SERIALIZATION_NVP(age_);}编译运行ok!
运行结果如下 t7.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="10">
<sdinfo class_id="0" tracking_level="1" version="0" object_id="_0">
<student_info class_id="1" tracking_level="1" version="0" object_id="_1">
<name_>wyp</name_>
<number_>0099</number_>
<grade_>1</grade_>
</student_info>
<age_>15</age_>
</sdinfo>
</boost_serialization>
完整代码如下
#include <fstream>#include <iostream>#include <algorithm>#include <boost/archive/xml_iarchive.hpp>#include <boost/archive/xml_oarchive.hpp>#include <boost/serialization/base_object.hpp>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_info() const{std::cout << name_ << " " << number_ << " " << grade_ << std::endl;}private:friend class boost::serialization::access;template<typename Archive>void serialize(Archive& ar, const unsigned int version){ar & BOOST_SERIALIZATION_NVP(name_);ar & BOOST_SERIALIZATION_NVP(number_);ar & BOOST_SERIALIZATION_NVP(grade_);}private:std::string name_;std::string number_;std::string grade_;};BOOST_SERIALIZATION_ASSUME_ABSTRACT(student_info)class middle_student : public student_info{public:middle_student() {}virtual ~middle_student() {}middle_student(const std::string& sn, const std::string& snm, const std::string& sg, int age): student_info(sn, snm, sg), age_(age){}virtual void print_info(){student_info::print_info();std::cout << age_ << std::endl;}private:friend class boost::serialization::access;template<typename Archive>void serialize(Archive& ar, const unsigned int version){ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(student_info);ar & BOOST_SERIALIZATION_NVP(age_);}private:int age_;};void save(){std::ofstream ofs("t7.xml");boost::archive::xml_oarchive oa(ofs);oa.template register_type<middle_student>(NULL);student_info* sdinfo = new middle_student("wyp", "0099", "1", 15);oa << BOOST_SERIALIZATION_NVP(sdinfo);delete sdinfo;}void load(){std::ifstream ifs("t7.xml");boost::archive::xml_iarchive ia(ifs);ia.template register_type<middle_student>(NULL);student_info* sdinfo = NULL;ia >> BOOST_SERIALIZATION_NVP(sdinfo);middle_student* mds = dynamic_cast<middle_student*>(sdinfo);mds->print_info();}void fun(){save();load();}
0 0
- boost::serialization 用基类指针转存派生类(错误多多,一波三折)
- 怎样用boost::serialization去序列化派生模板类
- 怎样用boost::serialization去序列化派生模板类(续)
- boost::serialization(1)基础
- boost::serialization
- boost serialization
- boost::serialization
- boost serialization
- boost::serialization
- Boost serialization
- boost中serialization模块的单体类
- boost::serialization中为泛型结构体(类)标注版本号
- 一波三折
- Learning boost 1 Serialization
- Learning boost 1 Serialization
- Learning boost Serialization
- boost::serialization学习笔记
- Boost::Serialization试用手记
- hadoop2.2.0本地库替换--centos6.4-64位
- mapreduce任务出错最大尝试次数
- umlの状态图
- ununtu 14.04下安装postgresql9.3.4
- 大龙的涂鸦之“代码生成器”(第二代)
- boost::serialization 用基类指针转存派生类(错误多多,一波三折)
- 机房收费系统——UML类图
- 使用JDK中的Proxy技术实现AOP功能
- 组合问题
- android 播放视频
- Android使用图片资源
- Tomcat—如何在Windows 7中修改Tomcat的端口号
- lca学习题
- iar 看输出二进制文件大小