繁体   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