Boost::Serialise 中序列化类的非侵入式方法是否使类可序列化?

qua*_*ant 2 c++ serialization boost

我试图了解 Boost 的序列化库(请参阅教程),并且非常喜欢序列化类的非侵入式方式,因为这意味着我可以将所有序列化代码放在单独的文件中:

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

class gps_position
{
public:
    int degrees;
    int minutes;
    float seconds;
    gps_position(){};
    gps_position(int d, int m, float s) :
        degrees(d), minutes(m), seconds(s)
    {}
};

namespace boost {
namespace serialization {

template<class Archive>
void serialize(Archive & ar, gps_position & g, const unsigned int version)
{
    ar & g.degrees;
    ar & g.minutes;
    ar & g.seconds;
}

} // namespace serialization
} // namespace boost
Run Code Online (Sandbox Code Playgroud)

虽然此方法提供了一个函数“serialise”,可用于序列化“gps_position”类,但我不确定该类是否是其本身序列化(即,在序列化/反序列化方面就像一个原语)已创建,或者如果我必须使用侵入式方法......

也就是说,如果我有另一个包含“gps_position”实例向量的类,当我尝试执行以下操作时,Boost 会知道在 Boost::serialization 命名空间中查找与“gps_position”参数匹配的重载“serialize”函数序列化父类?或者它只会显式查找类的“序列化”方法(在本例中找不到)?

我在教程中找不到这个问题的答案,希望有使用该库经验的人能够提供一些线索!

PS我不愿意“尝试一下”,因为我不知道失败应该是什么样子(Boost只会序列化“某事”吗?)...

goj*_*oji 5

虽然此方法提供了一个函数“serialise”,可用于序列化“gps_position”类,但我不确定一旦该函数具有该类本身是否可序列化(即,在序列化/反序列化方面就像一个原语)已创建,或者如果我必须使用侵入式方法......

是的,无论您使用哪种方法,该类都可以通过使用带有 boost.serialization 存档的“&”运算符的常规方法进行序列化。

也就是说,如果我有另一个包含“gps_position”实例向量的类,当我尝试执行以下操作时,Boost 会知道在 Boost::serialization 命名空间中查找与“gps_position”参数匹配的重载“serialize”函数序列化父类?或者它只会显式查找类的“序列化”方法(在本例中找不到)?

您还需要为父类提供序列化函数。您将在其中序列化类的每个成员,其方式与序列化子类的方式大致相同。

PS我不愿意“尝试一下”,因为我不知道失败应该是什么样子(Boost只会序列化“某事”吗?)...

只要尝试一下,就是你可以学到的最好的方法。这很可能是其他想要回答这个问题的人在简要查看文档后就会了解到的。

这是侵入式和非侵入式版本的非常快速的模型:

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <boost/serialization/access.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

// child class serialized using intrusive

struct child
{
  std::string name;

  child() = default;

  explicit child(const std::string& name)
    : name(name)
  { }

  template <class Archive>
  void serialize(Archive& ar, const unsigned int /* version */)
  {
    ar & name;
  }
};


struct parent
{
  std::vector<child> children;

  parent() = default;

  explicit parent(const std::vector<child>& children)
    : children(children)
  { }
};

// parent class serialized using non-instrusive

namespace boost {
namespace serialization {

template <class Archive>
void serialize(Archive& ar, parent& p, const unsigned int /* version */)
{
  ar & p.children;
}

}
}

int main()
{
  parent p1 {{child("one"), child("two"), child("three")}};

  std::stringstream ss;
  boost::archive::text_oarchive oa(ss);
  oa << p1;

  parent p2;
  boost::archive::text_iarchive ia(ss);
  ia >> p2;

  for (auto& child : p2.children) {
    std::cout << child.name << "\n";
  }
}
Run Code Online (Sandbox Code Playgroud)