BOOST_CLASS_EXPORT
Posted blfbuaa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BOOST_CLASS_EXPORT相关的知识,希望对你有一定的参考价值。
用基类的指针去转存派生类时除了上一篇boost::serialization
用基类指针转存派生类(错误多多,一波三折)之外。还有还有一种更简单的方法:
用BOOST_CLASS_EXPORT宏。
用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.
- 实例化未被引用的代码。
- 用一个外部的标识符关联被序列化的类。
其实该类未被显式引用即暗示这一要求。
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的主要内容,如果未能解决你的问题,请参考以下文章