簡體   English   中英

C ++ Boost序列化,構造函數和數據復制

[英]C++ Boost serialization, constructor and data copying

我正在嘗試了解boost庫的序列化工作原理,並且我只想確保我認為正確。

如果我保存對象(我只有該對象的指針),然后嘗試加載它,則序列如下:

  1. 調用此對象的構造函數。
  2. 復制數據。

問題是,如果構造函數使用該類的靜態成員(例如某些計數器),則會使我誤解有關已加載對象的信息。 我有基於靜態計數器的對象ID,並且(加載后)構造函數向控制台打印的對象ID不正確。 這似乎對我的程序沒有害處,因為在調用構造函數之后,一切都很好。 甚至析構函數也會向我輸出正確的對象ID。

我對這個順序正確嗎? 還是這里發生了其他“魔術”?

如果我保存對象(我只有指向該對象的指針),然后嘗試加載它,則序列如下:

  1. 調用此對象的構造函數。
  2. 復制數據。

你是對的。 當boost序列化庫加載數據時,只要使用serialize()成員函數模板,就會首先調用默認的構造函數,然后再復制數據。

這是一個例子。 您還可以看到執行結果: http : //melpon.org/wandbox/permlink/xlzdnK0UnZo48Ms2

#include <fstream>
#include <string>
#include <cassert>
#include <iostream>

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

class Person {
public:
    Person():id_(id_master_++) {
        std::cout << "Person() id = " << id_ << " and id_master_ is incremented to " << id_master_ <<std::endl;
    };
    ~Person() {
        std::cout << "~Person() id = " << id_ << std::endl;
    }
    Person(std::string const& name, int age)
        :id_(id_master_++),
         name_(name), 
         age_(age) {
        std::cout << "Person(std::string const&, int) id = " << id_ << " and id_master_ is incremented to " << id_master_ <<std::endl;
    }
    std::string const& name() const { return name_; }
    int age() const { return age_; }
private:
    static int id_master_;
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, unsigned int /*version*/)
    {
        ar & name_;
        ar & age_;
        std::cout << "before store or load id = " << id_ << std::endl;
        ar & id_; // *1
        std::cout << "after store or load id = " << id_ << std::endl;
    }
    int id_;
    std::string name_;
    int age_;
};

int Person::id_master_;

int main()
{
    {
        Person p1("John", 25);
        std::ofstream ofs("person.txt");
        boost::archive::text_oarchive oa(ofs);
        oa << p1;
    }
    {
        std::ifstream ifs("person.txt");
        boost::archive::text_iarchive ia(ifs);
        Person p2;
        ia >> p2;
        assert(p2.name() == "John");
        assert(p2.age() == 25);
    }
}

對象的ID被* 1的加載數據覆蓋。

這似乎對我的程序沒有害處,因為在調用構造函數之后,一切都很好。

有害或無害取決於您的情況。 對象會按預期反序列化,但在我的示例中,id_master_遞增為2。請注意這種行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM