我正在尝试理解Boost的序列化库(see tutorial),并且非常类似于序列化类的非侵入式方法,因为这意味着我可以将所有序列化代码放在单独的文件中:
#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
虽然这个方法提供了一个函数'serialise',它可以用来序列化'gps_position'类,但我不确定这个类本身是否是 serializable (即表现得像一个原语)序列化/反序列化的术语)一旦创建了这个函数,或者我必须使用侵入式方法......
也就是说,如果我有另一个包含'gps_position'实例的向量的类,Boost会知道在Boost :: serialization命名空间中查找重载的'serialize'函数,该函数匹配'gps_position'参数我尝试序列化父类?或者它只是明确地查找类的'serialize'方法(在这个实例中它找不到)?
我在教程中找不到这个问题的答案,并且希望有经验的人可以使用这个库,这可能会有所帮助!
P.S我不愿意“只是尝试一下”,因为我不知道失败应该是什么样的(Boost只会序列化“某些东西”?)......
答案 0 :(得分:4)
虽然此方法提供了可以使用的“序列化”功能 为了序列化'gps_position'类,我不确定该类 它本身是可序列化的(即就行为而言就像一个原始行为 序列化/反序列化)一旦创建了这个函数,或者如果 我必须使用侵入式方法...
是的,该课程将通过使用'&amp;'的常规方法进行序列化。具有boost.serialization存档的运算符,无论您使用哪种方法。
也就是说,如果我有另一个类,其中包含一个向量 'gps_position'实例,Boost会知道要查找重载 'serialize'函数在Boost :: serialization命名空间中匹配a 当我尝试序列化父类时,'gps_position'参数?要么 它只会明确地查找类的'serialize'方法 (在这种情况下它不会找到)?
您还需要为父类提供序列化功能。在其中,您将以与完成子类相同的方式序列化类的每个成员。
P.S我不愿意“试试”,因为我不知道失败了 应该看起来像(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";
}
}
答案 1 :(得分:1)
虽然这个方法提供了一个函数'serialise',可用于序列化'gps_position'类,但我不确定该类本身是否可序列化(即,在序列化/反序列化方面就像一个原语)这个函数已经创建,或者如果我必须使用侵入式方法......
类型
T
可序列化当且仅当下列情况之一为真时:
- 它是一种原始类型。 [...]
- 这是一个类类型,根据下面详述的原型声明了以下之一:
- 班级成员函数
serialize
- 全局函数
serialize
- 它是指向可序列化类型的指针。
- 它是对可序列化类型的引用。
- 它是可序列化类型的本机C ++数组。
也就是说,如果我有另一个包含'gps_position'实例的向量的类,Boost会知道在Boost :: serialization命名空间中查找重载的'serialize'函数,该函数匹配'gps_position'参数我尝试序列化父类?或者它只是明确地查找类的'serialize'方法(在这个实例中它找不到)?
没有定义成员函数serialize
且没有定义全局函数serialize
的类类型(后者具有类类型的非const ref作为第二个参数)不符合 Serializable 概念。
但是,在文档的同一页面上:
上述设施足以实现所有STL容器的序列化。实际上,这已经完成并且已经包含在库中。
也就是说,如果您包含相应的头文件<boost/serialization/vector.hpp>
,则矢量模板的特化将变为可序列化,如果其value_type
可序列化
由于您的课程gps_position
可序列化,如果您包含上述标题,则std::vector<gps_position>
也可序列化。但是,根据规则,包含此类向量的类不会自动可序列化。它需要有成员或非成员函数serialize
:
#include <boost/serialization/vector.hpp>
struct gps_position { int i; };
struct gps_path { std::vector<gps_position> v; }
template<class Archive>
void serialize(Archive& ar, gps_position& p, const unsigned int)
{ ar & p.i; }
// by declaring this function, `gps_position` is Serializable
template<class Archive>
void serialize(Archive& ar, gps_path& p, const unsigned int)
{ ar & p.v; }
// as `v` is Serializable (because `gps_position` is Serializable),
// you can leave it to the boost library to serialize the individual
// elements of the vector
注意:该功能不必是全局的。如文档的链接页面所述,支持非限定查找和ADL:
为了获得最大的可移植性,请在命名空间
boost::serialization
中包含任何自由函数模板和定义。如果可移植性不是问题,并且正在使用的编译器支持ADL(Argument Dependent Lookup),则自由函数和模板可以位于以下任何名称空间中:
boost::serialization
- 存档类的命名空间
- 要序列化的类型的命名空间