首先来看前面实例的一段代码:
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 文档)
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,布布扣,bubuko.com
原文:http://blog.csdn.net/xiaoliangsky/article/details/24939647