boost.serialization庫是一個很是強大又易用的序列化庫,用於對象的保存與持久化等。網絡
使用base_object能夠在序列化子類的同時也序列化父類,以此得到足夠的信息來從文件或網絡數據中反序列化出子類。函數
最近在工做中卻遇到這樣一個問題,代碼示例以下this
struct Field { friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & boost::serialization::make_nvp("FieldImpl", serializeString); } string serializeString; }; template<typename ValueType> struct SubField : Field { typedef ValueType type; friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & boost::serialization::make_nvp("CommonField", boost::serialization::base_object<Field>(*this)); ar & boost::serialization::make_nvp("data", data); } type data; };
有超類Field與模板子類SubField(可能還會有其餘子類),如今須要經過超類指針多態序列化子類spa
首先想到的辦法是將超類serialize方法簽名爲virtual,經過多態調用子類serialize方法。可是這倒是不可能的,由於serialize方法是一個模板函數,不能爲vitual方法,因此這條路不通。指針
無奈之下只好直接嘗試一下:code
shared_ptr<SubField<int> > spSub(new SubField<int>()); spSub->data = 10; spSub->serializeString = "sub"; shared_ptr<Field> spField(new Field()); spField = boost::static_pointer_cast<Field>(spSub); std::stringstream ss; boost::archive::xml_oarchive ar(ss, boost::archive::archive_flags::no_header); ar << boost::serialization::make_nvp("Field", spField); std::cout << ss.str();
不出所料,運行時拋出了異常。
從新閱讀手冊及serialization文檔,意外發現幾個關鍵詞,BOOST_SERIALIZATION_ASSUME_ABSTRACT和BOOST_CLASS_EXPORT,繼續求助sof後,終於找到了問題得解決辦法,原文連接以下:xml
http://stackoverflow.com/questions/8370727/error-serializing-an-abstract-class-with-boostblog
第一種是使用BOOST_SERIALIZATION_ASSUME_ABSTRACT配合archive的template register_type方法繼承
第二種是直接使用BOOST_CLASS_EXPORT,導出全部繼承鏈中的class
對於第二種方法直接使用
BOOST_CLASS_EXPORT(Field) BOOST_CLASS_EXPORT(SubField<int>)
問題解決,輸出爲: