2009-08-26 6 views
11

Ich möchte/unserialize serialisiert werden folgende Klassen:Wie man abgeleitete Vorlagenklassen mit Boost.serialize serialisiert?

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

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

I boost.serialize docs lesen und die Sayed, dass Sie Klassen anmelden. Ich kann sie im Konstruktor registrieren. Aber es wird Probleme mit dem Laden geben, da die Registrierung dynamisch und nicht statisch ist (Wie ich verstanden habe, müssen Sie Klassen vor der Serialisierung/Deserialisierung registrieren).

Wie speichern/laden Sie diese Art von Klassen?

Antwort

15

Zuerst sagen steigern, dass Eigenschaft abstrakt ist, ist nicht immer erforderlich:

BOOST_SERIALIZATION_ASSUME_ABSTRACT(Feature); 

Die Serialisierungsmethode mehr oder weniger sollte wie folgt aussehen:

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

Jetzt kommt der schwierige Punkt Klasse registrieren in serialisieren/deserialisieren:

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; 

Wenn Sie explizite Registrierung somewh ausblenden müssen Um es automatischer zu machen, gibt es die Idee, eine spezielle Funktor-Vorlage zu erstellen, die eine abgeleitete Klasse registriert, alle verfügbaren Variablen erstellt und in eine einzige Liste einfügt, die eine statische Methode der Klasse Feature sie alle registriert. Jedoch wird das Problem sein, dass Sie Registrierung für alle Version des Archivs benötigen, gerade jetzt weiß ich nicht, ob polymorphes Archiv den Job macht oder nicht.

+0

Ich denke, es gibt einen Fehler in Zeile 11 der ersten Code-Box. Wenn ich mich nicht irre, sollte "ar &" links von "boost :: serialization :: base_object" stehen. Schöne Antwort aber! –

+3

@lionbest: Sollten Sie 'BOOST_SERIALIZATION_BASE_OBJECT_NVP' nicht anstelle von' boost :: serialization :: base_object (* this); ' – Cookie

+0

verwenden Ich denke, dass Sie Namen angeben möchten, wenn Sie mehr als eine Basisklasse haben. Ich denke nicht, dass dieses Makro hier gebraucht wird, aber sicher, dass Sie vielleicht eines haben wollen. – Arpegius

Verwandte Themen