2009-08-26 16 views
11

me gustaría para serializar/unserialize siguientes clases:¿Cómo serializar las clases de plantilla derivadas con Boost.serialize?

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

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

leí documentos boost.serialize y el Sayed que debe registrar clases. Puedo registrarlos en el constructor. Pero habrá problemas con la carga, ya que el registro será dinámico, no estático (como entendí, debe registrar las clases antes de la serialización/deserialización).

¿Cómo guardar/cargar este tipo de clases?

Respuesta

15

En primer lugar decirle a impulsar esa característica es abstracta, no siempre se necesita:

BOOST_SERIALIZATION_ASSUME_ABSTRACT(Feature); 

El método de serialización debe verse más o menos así:

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

Ahora el punto difícil es dar de alta clase en serializar/deserializar:

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; 

Si necesita ocultar el registro explícito somewh Para hacerlo más automático, hay una idea de crear una plantilla de functor especial que registre una clase derivada, cree todas las disponibles y coloque en una sola lista, ese método estático de la clase Feature las registraría todas. Sin embargo, el problema será que necesita registrarse para todas las versiones del archivo, en este momento no sé si el archivo polimórfico hará el trabajo o no.

+0

Creo que hay un error en la línea 11 del primer cuadro de código. Si no me equivoco, debe tener "ar" a la izquierda de "boost :: serialization :: base_object". ¡Buena respuesta! –

+3

@lionbest: ¿No debería usar 'BOOST_SERIALIZATION_BASE_OBJECT_NVP' en lugar de' boost :: serialization :: base_object (* this); ' – Cookie

+0

Creo que es posible que desee especificar el nombre si tiene más de una clase base. No creo que esta macro sea necesaria aquí, pero seguro que querrás tener una. – Arpegius

Cuestiones relacionadas