BOOST_CLASS_EXPORT
用基类的指针去转存派生类时除了上一篇boost::serialization
用基类指针转存派生类(错误多多,一波三折)之外。还有还有一种更简单的方法:
用BOOST_CLASS_EXPORT宏。
以下我们来分析如何用BOOST_CLASS_EXPORT来实现
用基类的指针去转存派生类。
首先来看前面实例的一段代码:
void save()
{
std::ofstream ofs("t7.xml");
boost::archive::xml_oarchive oa(ofs);
student_info* sdinfo = new middle_student("wyp", "0099", "1", 15);
oa << BOOST_SERIALIZATION_NVP(sdinfo);//#1
delete sdinfo;
}
当程序运行到#1时就会抛出异常:boost::archive::archive_exception at memory location 0x0017eb30...
boost文档解释是派生类没有实例化(这里是个人理解。。
。
。“实例化”究竟什么意思也不太理解。。。)。
当我们在#1前面加上注冊的代码时
oa.template register_type<middle_student>(NULL);
实际上就相当于“实例化”。看看register_type的实现代码:
template<class T>
const basic_pointer_oserializer *
register_type(const T * = NULL){
const basic_pointer_oserializer & bpos =
boost::serialization::singleton<
pointer_oserializer<Archive, T>
>::get_const_instance();
this->This()->register_basic_serializer(bpos.get_basic_serializer());
return & bpos;
}
代码大概就是用单件模式申请一个对象的const指针,预计这个实例化就是为T申请内存。
然后看看BOOST_CLASS_EXPORT宏
#define BOOST_CLASS_EXPORT(T) \
BOOST_CLASS_EXPORT_GUID( \
T, \
BOOST_PP_STRINGIZE(T) \
) \
实际上是BOOST_CLASS_EXPORT_GUID宏的定义。继续看看这个宏
#define BOOST_CLASS_EXPORT_GUID(T, K) \
BOOST_CLASS_EXPORT_KEY2(T, K) \
BOOST_CLASS_EXPORT_IMPLEMENT(T) \
原来这个宏展开式两个宏的定义。先看BOOST_CLASS_EXPORT_KEY2(T,K)这个宏
#define BOOST_CLASS_EXPORT_KEY2(T, K) \
namespace boost { \
namespace serialization { \
template<> \
struct guid_defined< T > : boost::mpl::true_ {}; \
template<> \
inline const char * guid< T >(){ \
return K; \
} \
} /* serialization */ \
} /* boost */ \
这个宏实际上做了一件这种事:返回了一个唯一标记T的const char*字符串。
接下看看看BOOST_CLASS_EXPORT_IMPLEMENT(T)这个宏:
#define BOOST_CLASS_EXPORT_IMPLEMENT(T) \
namespace boost { \
namespace archive { \
namespace detail { \
namespace extra_detail { \
template<> \
struct init_guid< T > { \
static guid_initializer< T > const & g; \
}; \
guid_initializer< T > const & init_guid< T >::g = \
::boost::serialization::singleton< \
guid_initializer< T > \
>::get_mutable_instance().export_guid(); \
}}}} \
看看这段代码是不是和register_type实现的代码非常类似:用单件模式返回一个指针。
这就验证了“实例化”事实上就是申请T的内存。
至此我们能够看出BOOST_CLASS_EXPORT和register_type具有类似的功能:(boost 文档)
- Instantiates code which is not otherwise referred to.
- Associates an external identifier with the class to be serialized. The fact that the class isn't explicitly referred to implies this requirement.
- 实例化未被引用的代码。
- 用一个外部的标识符关联被序列化的类。
其实该类未被显式引用即暗示这一要求。
好。转回来。如今看看详细如何用BOOST_CLASS_EXPORT这个宏来实现
1.基类文件:student_info.h
class student_info
{
public:
student_info() {}
virtual ~student_info() {}
student_info(const std::string& sn, const std::string& snm, const std::string& sg);
virtual void print_info() const;
private:
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive& ar, const unsigned int version);
private:
std::string name_;
std::string number_;
std::string grade_;
};
2派生类文件middle_student.h
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);
virtual void print_info();
private:
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive& ar, const unsigned int version);
private:
int age_;
};
3.main.cpp
#include <fstream>
#include <boost\archive\text_iarchive.hpp>
#include <boost\archive\text_oarchive.hpp>
#include <boost\serialization\export.hpp> #include "student_info.h" #include "middle_student.h"
BOOST_CLASS_EXPORT(middle_student)
//#1
//#2 void save()
{
std::ofstream ofs("t7.xml");
boost::archive::xml_oarchive oa(ofs);
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);
student_info* sdinfo = NULL;
ia >> BOOST_SERIALIZATION_NVP(sdinfo);
middle_student* mds = dynamic_cast<middle_student*>(sdinfo);
mds->print_info();
} int main()
{
save();
load();
return 0;
}
看见红色字体的两行没有,就是这样用BOOST_CLASS_EXPORT宏,这样就不用注冊派生类。
假如又有一个student_info的派生类xxx_student,且头文件为"xxx_student.h",你仅仅须要
在#1加入#include "xxx_student.h"
在#2加入BOOST_CLASS_EXPORT(xxx_student)
这样你就也能使用基类student_info的指针来转存派生了xxx_student。
BOOST_CLASS_EXPORT的更多相关文章
- 【boost】使用serialization库序列化子类
boost.serialization库是一个非常强大又易用的序列化库,用于对象的保存与持久化等. 使用base_object可以在序列化子类的同时也序列化父类,以此获得足够的信息来从文件或网络数据中 ...
- boost serialization
Archive An archive is a sequence of bytes that represented serialized C++ objects. Objects can be ad ...
随机推荐
- vue项目,封装api并使用
封装api index.js let uploadBase = '' if(process.env.NODE_ENV === 'production'){ uploadBase = 'https:// ...
- C语言基础 (2) linux命令
01.课程回顾 链接 ln 1.txt aaa.txt 硬链接 (两个相互独立 删除一个另外一个还在) ln -s 1.txt aaa.txt软连接 (后面的是快捷方式) 硬链接只能是文件,软连接可 ...
- BZOJ 1444 [JSOI2009]有趣的游戏 (Trie图/AC自动机+矩阵求逆)
题目大意:给你$N$个长度相等且互不相同的模式串,现在有一个字符串生成器会不断生成字符,其中每个字符出现的概率是$p_{i}/q_{i}$,当生成器生成的字符串包含了某个模式串,则拥有该模式串的玩家胜 ...
- 洛谷 P4932 浏览器 (思维题)
题目大意:给你一个序列,求满足$x_{i}\: xor\; x_{j}$在二进制下1的数量为奇数的数对数量 打月赛的时候真没想出来,还是我太弱.. xor意义下,对于两个数,假设它们两个每一位都是2个 ...
- vmware vsphere出现“需要整合虚拟机磁盘”的告警处理方法(完整版)
vmware vsphere出现“需要整合虚拟机磁盘”的告警 处理步骤: 1.选择对应虚机,快照——整合 (不行看下一条) 通常情况执行完第一步就好了 2.如果整合报错,提示文件锁定 2.1 新建快照 ...
- wordcontent结对编程
合作者:201631062625 201631062127 代码地址:https://gitee.com/yzpdegit/ts 本次作业链接:https://www.cnblogs.com/yang ...
- python基础7(函数 Ⅱ)
1.python代码运行遇到函数时 从python解释器开始执行之后,就在内存中开辟了一个空间 每当遇到一个变量的时候,就把变量名和值之间的对应关系记录下来. 但是当遇到函数定义的时候解释器只是象征性 ...
- 紫书 习题 8-16 UVa 1618 (中途相遇法)
暴力n的四次方, 然而可以用中途相遇法的思想, 分左边两个数和右边两个数来判断, 最后合起来判断. 一边是n平方logn, 合起来是n平方logn(枚举n平方, 二分logn) (1)两种比较方式是相 ...
- 紫书 例题8-15 UVa 12174 (滑动窗口)
这道题就是给你一n长序列, 然后把这个序列按顺序分成很多段, 每段长s(最前面可以小于s, 只有第一段的后半段, 最后面也同样, 只有最后一段的前半段), 然后要求是每一段里面没有重复的数, 问你有几 ...
- POJ——T2553 The Bottom of a Graph
http://poj.org/problem?id=2553 Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 10987 ...