【boost】使用serialization庫序列化子類

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/1332602/how-to-serialize-derived-template-classes-with-boost-serialize對象

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>)

問題解決,輸出爲:

相關文章
相關標籤/搜索