首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

Boost.Serialization 進階:拆分 serialize 為 save/load 實現版本控制

     編輯:C++ 入門

在上一篇《Boost.Serialization 用基類指針轉存派生類》中,我們使用單一的 serialize 函數實現序列化。但實際上,該函數根據歸檔類型(保存或加載)會表現出不同行為:使用 xxx_oarchive 時等價於保存數據,使用 xxx_iarchive 時等價於加載數據。因此,我們可以將其拆分為獨立的 save 和 load 函數,從而獲得更精細的控制權,特別是處理版本升級時極為有用。

拆分前的 serialize 寫法

private:
    friend class boost::serialization::access;
    template<typename Archive>
    void serialize(Archive& ar, const unsigned int version) {
        ar & BOOST_SERIALIZATION_NVP(name_);
        ar & BOOST_SERIALIZATION_NVP(number_);
        ar & BOOST_SERIALIZATION_NVP(grade_);
    }

拆分後的 save/load 寫法

template<typename Archive>
void save(Archive& ar, const unsigned int version) const {
    ar << BOOST_SERIALIZATION_NVP(name_);
    ar << BOOST_SERIALIZATION_NVP(number_);
    ar << BOOST_SERIALIZATION_NVP(grade_);
}

template<typename Archive>
void load(Archive& ar, const unsigned int version) {
    ar >> BOOST_SERIALIZATION_NVP(name_);
    ar >> BOOST_SERIALIZATION_NVP(number_);
    ar >> BOOST_SERIALIZATION_NVP(grade_);
}

關鍵宏:BOOST_SERIALIZATION_SPLIT_MEMBER()

必須在類內部添加此宏,它實現了一個模板函數,內部調用 boost::serialization::split_member。該函數利用 traits 技術根據 Archive::is_saving 推導出 member_saver 或 member_loader 類型,進而調用我們定義的 save/load。這也是為什麼必須聲明 boost::serialization::access 為友元類的原因——它需要訪問私有的 save/load 成員函數。

完整類示例

class student_info {
public:
    student_info() {}
    virtual ~student_info() {}
    student_info(const std::string& sn, const std::string& snm,
                 const std::string& sg, const std::string& cs)
        : name_(sn), number_(snm), grade_(sg), class_(cs) {}
    virtual void print_info() const {
        std::cout << name_ << " " << number_ << " "
                  << grade_ << " " << class_ << " ";
    }
private:
    friend class boost::serialization::access;
    template<typename Archive>
    void save(Archive& ar, const unsigned int version) const {
        ar << BOOST_SERIALIZATION_NVP(name_);
        ar << BOOST_SERIALIZATION_NVP(number_);
        ar << BOOST_SERIALIZATION_NVP(grade_);
        ar << BOOST_SERIALIZATION_NVP(class_);
    }
    template<typename Archive>
    void load(Archive& ar, const unsigned int version) {
        ar >> BOOST_SERIALIZATION_NVP(name_);
        ar >> BOOST_SERIALIZATION_NVP(number_);
        ar >> BOOST_SERIALIZATION_NVP(grade_);
    }
    BOOST_SERIALIZATION_SPLIT_MEMBER() // 必須在類內部
private:
    std::string name_;
    std::string number_;
    std::string grade_;
    std::string class_;
};

非侵入式序列化補充

除了侵入式寫法,也可以採用非侵入式:在類外部定義 serialize 函數並聲明為友元,適合無法修改類定義的場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved