简体   繁体   English

C ++ Boost序列化,构造函数和数据复制

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

I am trying to understand how the serialization by boost library works, and I want to just ensure that I think correctly. 我正在尝试了解boost库的序列化工作原理,并且我只想确保我认为正确。

If I save object (I have only pointer to this object) and then try to load it, the sequence is following: 如果我保存对象(我只有该对象的指针),然后尝试加载它,则序列如下:

  1. Calling the constructor of this object. 调用此对象的构造函数。
  2. Copying the data. 复制数据。

The thing is if constructor use the static members (for example some counters) of the class, it gives me misleading information about loaded objects. 问题是,如果构造函数使用该类的静态成员(例如某些计数器),则会使我误解有关已加载对象的信息。 I have object's ID based on static counter and (after loading) object's ID printed by constructor to console is incorrect. 我有基于静态计数器的对象ID,并且(加载后)构造函数向控制台打印的对象ID不正确。 It seems to make no harm to my program, because after calling constructor all works great. 这似乎对我的程序没有害处,因为在调用构造函数之后,一切都很好。 Even the destructor prints me correct ID of object. 甚至析构函数也会向我输出正确的对象ID。

Am I right about this sequence? 我对这个顺序正确吗? Or maybe some other "magic" is happening here? 还是这里发生了其他“魔术”?

If I save object (I have only pointer to this object) and then try to load it, > the sequence is following: 如果我保存对象(我只有指向该对象的指针),然后尝试加载它,则序列如下:

  1. Calling the constructor of this object. 调用此对象的构造函数。
  2. Copying the data. 复制数据。

You are right. 你是对的。 When boost serialization library loads the data, first the default constructor is called, and then data are copied as long as you use serialize() member function template. 当boost序列化库加载数据时,只要使用serialize()成员函数模板,就会首先调用默认的构造函数,然后再复制数据。

Here is an example. 这是一个例子。 You can also see execution result: http://melpon.org/wandbox/permlink/xlzdnK0UnZo48Ms2 您还可以看到执行结果: 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);
    }
}

The object's id is overwritten by loaded data at *1. 对象的ID被* 1的加载数据覆盖。

It seems to make no harm to my program, because after calling constructor all works great. 这似乎对我的程序没有害处,因为在调用构造函数之后,一切都很好。

Harmful or not harmful is depends on your situation. 有害或无害取决于您的情况。 Objects are deserialized as you expected, but in my example, id_master_ is incremented to 2. Be caraful that behavior. 对象会按预期反序列化,但在我的示例中,id_master_递增为2。请注意这种行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM