2009-08-26 14 views
11

Mi piacerebbe serializzare/unserialize seguenti classi:Come serializzare le classi template derivate con Boost.serialize?

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

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

ho letto docs boost.serialize e Sayed che è necessario registrarsi classi. Posso registrarli in costruttore. Ma ci saranno problemi con il caricamento, in quanto la registrazione sarà dinamica, non statica (come ho capito, è necessario registrare le classi prima della serializzazione/deserializzazione).

Come salvare/caricare questo tipo di classi?

risposta

15

innanzitutto dire spinta che Caratteristica è astratta, non è sempre necessario:

BOOST_SERIALIZATION_ASSUME_ABSTRACT(Feature); 

Il metodo di serializzazione dovrebbe apparire più o meno così:

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

Ora il punto delicato è quello di registrare classe in serialize/deserialize:

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; 

Se è necessario nascondere la registrazione esplicita di somewh Prima di renderlo più automatico, vi è l'idea di creare un modello di functor speciale che registri una classe derivata, crei tutto disponibile e inserisca una sola lista, che un metodo statico di classe Feature li registrerebbe tutti. Tuttavia, il problema sarà che è necessaria la registrazione per tutte le versioni di archivio, in questo momento non so se l'archivio polimorfico farà il lavoro o meno.

+0

Penso che ci sia un bug nella riga 11 della prima casella di codice. Se non sbaglio, dovresti avere "ar &" a sinistra di "boost :: serialization :: base_object". Bella risposta però! –

+3

@lionbest: non dovresti usare 'BOOST_SERIALIZATION_BASE_OBJECT_NVP' invece di' boost :: serialization :: base_object (* this); ' – Cookie

+0

Penso che potresti voler specificare il nome se hai più di una classe base. Non penso che questa macro sia necessaria qui, ma sicuramente potresti averne voglia. – Arpegius

Problemi correlati