2009-08-26 4 views
11

私は/アンシリアライズ以下のクラスをシリアル化したい:私はboost.serializeのドキュメントを読んで、あなたがクラスを登録しなければならないことサイードBoost.serializeで派生テンプレートクラスをシリアル化する方法は?

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

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

。 コンストラクタに登録することができます。しかし、登録はダイナミックではなく、静的ではないため、読み込みに問題があります(理解したように、シリアライズ/デシリアライズの前にクラスを登録する必要があります)。

これらのクラスを保存/ロードするにはどうすればよいですか?

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); 
} 

今、トリッキーなポイントは、クラスを登録することである

答えて

15

まず、抽象的で常に必要とされていないという特徴を後押し伝えますシリアライズ/デシリアライズ時:

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; 

明示的に登録することを非表示にする必要がある場合は、それをもっと自動化するには、ある派生クラスを登録する特別なFunctorテンプレートを作成し、すべてのavaibleを作成して単一のリストに入れ、Featureクラスの1つの静的メソッドがそれらをすべて登録するという考えがあります。しかし、問題はあなたがアーカイブのすべてのバージョンの登録が必要なことです、今は多形アーカイブが仕事をするかどうかわかりません。

+0

最初のコードボックスの11行目にバグがあります。私が間違っていないなら、 "boost :: serialization :: base_object"の左に "ar&"をつけてください。しかし、ニースの答え! –

+3

@lionbest: 'boost :: serialization :: base_object (* this);の代わりに' BOOST_SERIALIZATION_BASE_OBJECT_NVP'を使うべきではありません。 – Cookie

+0

基本クラスが2つ以上ある場合は、名前を指定したいと思うかもしれません。私はこのマクロがここで必要とは思わないが、確かにあなたは1つ持っていたいかもしれない。 – Arpegius