如何使用 Boost.serialize 序列化派生模板类?

Posted

技术标签:

【中文标题】如何使用 Boost.serialize 序列化派生模板类?【英文标题】:How to serialize derived template classes with Boost.serialize? 【发布时间】:2010-11-22 21:17:58 【问题描述】:

我想序列化/反序列化以下类:

class Feature
...
virtual string str()=0;
;

template<typename T>
class GenericFeature : public Feature
T value;
...
virtual string str();
;

我阅读了 boost.serialize 文档,并说您必须注册课程。 我可以在构造函数中注册它们。但是加载会有问题,因为注册是动态的,而不是静态的(据我了解,您必须在序列化/反序列化之前注册类)。

如何保存/加载这些类型的类?

【问题讨论】:

【参考方案1】:

首先告诉 boost Feature 是抽象的,并不总是需要:

BOOST_SERIALIZATION_ASSUME_ABSTRACT(Feature);

序列化方法应该差不多是这样的:

template<class Archive> 
void Feature::serialize(Archive & ar, const unsigned int version)

   ar & BOOST_SERIALIZATION_NVP(some_member);



template<typename T,class Archive> 
void GenericFeature<T>::serialize(Archive & ar, const unsigned int version)

   ar & boost::serialization::base_object<Feature>(*this);  //serialize base class
   ar & BOOST_SERIALIZATION_NVP(some_other_member);

现在棘手的一点是在序列化/反序列化中注册类:

boost::archive::text_iarchive inputArchive(somesstream);

boost::archive::text_oarchive outputArchive(somesstream);

//something to serialize
Feature* one = new GenericFeature<SomeType1>();
Feature* two = new GenericFeature<SomeType2>();
Feature* three = new GenericFeature<SomeType3>();

//register our class, must be all of posible template specyfication    
outputArchive.template register_type< GenericFeature<SomeType1> >();
outputArchive.template register_type< GenericFeature<SomeType2> >();
outputArchive.template register_type< GenericFeature<SomeType3> >();

// now simply serialize ;-]
outputArchive << one << two << three;

// register class in deserialization
// must be the same template specification as in serialize
// and in the same correct order or i'm get it wrong ;-D   
inputArchive.template register_type< GenericFeature<SomeType1> >();
inputArchive.template register_type< GenericFeature<SomeType2> >();
inputArchive.template register_type< GenericFeature<SomeType3> >();

Feature* another_one;
Feature* another_two;
Feature* another_three;

// and deserialize ;-]
inputArchive >> another_one >> another_two >> another_three;

如果您需要在某处隐藏显式注册并使其更加自动化,则可以制作特殊的仿函数模板来注册一个派生类,创建所有可用并放入一个列表中,该类 Feature 的一个静态方法将注册商场。但是问题是您需要注册所有版本的存档,现在我不知道多态存档是否可以完成这项工作。

【讨论】:

我认为第一个代码框的第 11 行有一个错误。如果我没记错的话,你应该在“boost::serialization::base_object”的左边有“ar &”。不错的答案! @lionbest:你不应该使用BOOST_SERIALIZATION_BASE_OBJECT_NVP而不是boost::serialization::base_object&lt;Feature&gt;(*this); 如果您有多个基类,我认为您可能需要指定名称。我认为这里不需要这个宏,但你肯定想要一个。 @Arpegius 你有隐藏显式注册的例子吗? @DavidDoria 对不起,我没有,我发现它有问题,因为有许多类型的档案。可能已经有更好的方法了。一般的想法是让 FeutureRegistree 接口和模板 TypedFeutureRegistree 带有构造函数,它将其名称和指针添加到静态排序映射的单例。每个需要注册的类都需要一个 TypedFeutureRegistree 的静态声明,女巫将保留名称和版本 ID。从排序的映射中运行小于序列化版本的每个对象,将确保所有类都以正确的顺序注册。

以上是关于如何使用 Boost.serialize 序列化派生模板类?的主要内容,如果未能解决你的问题,请参考以下文章

强大的 boost::variant 序列化

EasyDL-SDK树莓派部署1

树莓派与python

"流"派家族,一脉相承

如何使用 树莓派连接摄像头拍照

如何让树莓派默认启动进入图形界面