2009-08-26 4 views
11

나는/때 unserialize 다음과 같은 클래스를 직렬화하고 싶습니다 : 나는 boost.serialize의 문서를 읽고 당신이 클래스를 등록해야 사예드Boost.serialize로 파생 된 템플릿 클래스를 직렬화하는 방법은 무엇입니까?

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

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

. 생성자에 등록 할 수 있습니다. 하지만로드가 문제가 될 것입니다. 등록은 동적이 아닌 정적이 될 것입니다. (필자가 이해 하듯이 직렬화/직렬화 이전에 클래스를 등록해야합니다.)

이러한 종류의 클래스를 저장 /로드하는 방법은 무엇입니까?

답변

15

먼저 그 기능이 추상적 인 향상 말은 항상 필요하지 않습니다 : 이제 까다로운 점은 클래스를 등록하는 것입니다

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_SERIALIZATION_ASSUME_ABSTRACT(Feature); 

직렬화 방법은 다음과 같이 더 많거나 적은 찾아야한다 직렬화/역 직렬화 중 :

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 템플릿을 작성하는 것이 좋습니다.이 클래스는 Feature 클래스의 한 정적 메소드를 모두 등록합니다. 그러나 문제는 아카이브의 모든 버전에 대한 등록이 필요하며, 현재 다형성 아카이브가 작업을 수행하는지 여부는 알 수 없습니다.

+0

첫 번째 코드 상자의 11 번째 행에 버그가 있다고 생각합니다. 실수가 아니라면 "boost :: serialization :: base_object"왼쪽에 "ar &"이 있어야합니다. 그래도 좋은 대답! –

+3

@lionbest :'boost :: serialization :: base_object (* this); 대신'BOOST_SERIALIZATION_BASE_OBJECT_NVP'을 써야하지 않습니까? – Cookie

+0

기본 클래스가 두 개 이상있는 경우 이름을 지정할 수 있습니다. 이 매크로는 여기에 필요하지 않다고 생각하지만 확실한 매크로를 원할 수 있습니다. – Arpegius

관련 문제