2012-03-15 13 views
6

Ho letto attraverso un sacco di domande simili ma non ho trovato la risposta. Sto usando Visual Studio 2010 e boost 1.47.serializzazione boost dell'oggetto derivato non chiama serialize derivato()

Ecco il codice, è completo e compilabile:

#include "stdafx.h" 

#include <string> 
#include <sstream> 

#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 

#include <boost/serialization/export.hpp> 

using namespace std; 

class BaseObject 
{ 
public: 

    BaseObject(void) { }; 
    virtual ~BaseObject(void) { }; 

    template<class Archive> 
     void serialize(Archive &ar, const unsigned int version) 
     { /* nothing happens here */ }; 
}; 

class DerivedObject : public BaseObject 
{ 
public: 

    string text; 

public: 

    DerivedObject(void) { }; 
    ~DerivedObject(void) { }; 

    template<class Archive> 
     void serialize(Archive &ar, const unsigned int version) 
     { 
      ar & text; 
     }; 
}; 

BOOST_CLASS_EXPORT(DerivedObject) 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    DerivedObject der; 
    der.text = "Testing!"; 

    std::ostringstream os; 
    boost::archive::text_oarchive oa(os); 
    oa.register_type<DerivedObject>(); 

    // I made a DerivedObject, but I'm casting it to a BaseObject 
    // as the serialization code should not have to know what type it is 
    BaseObject *base = &der; 
    // now serialize it 
    oa << *base; 

    printf("serialized: %s\r\n",os.str().c_str()); 

    return (0); 
} 

si può vedere che è reale semplice, e ho aggiunto la magia BOOST_CLASS_EXPORT e oa.register_type che dovrebbe assicurarsi DerivdObject :: Serialize() viene chiamato anche se non è un metodo virtuale .. ma viene chiamato solo serialize() in BaseObject. Forse un problema specifico di Visual C++? Si prega di consulenza?

+1

Il tuo 'BaseObject :: serialize' non dovrebbe essere contrassegnato come' virtuale'? – Nick

+0

No, è un modello, non può t –

+0

Buon punto - non ho notato il bit del template! – Nick

risposta

2

Come descritto nel boost serialization documentation è necessario dire al vostro classe derivata per chiamare il codice di serializzazione classe di base. Scrivi semplicemente il tuo metodo serialize di classe derivato in questo modo:

0

Non ho provato questo nel debugger o altro, ma sembra che potrebbe essere un caso di affettare. Forse si potrebbe scoprire modificando il codice di serializzare dal puntatore o per riferimento invece che per valore, in questo modo ...

BaseObject *base = &der; 
oa << base; // Serialize a pointer 

... o ...

BaseObject& base = der; 
oa << base; // Serialize a reference 
+0

Grazie, ma il primo lancia un'eccezione, qualcosa di classe non registrata, e l'altro fa sostanzialmente la stessa cosa del mio codice. Stesso risultato ... – CodeOrElse

+0

Mi sono reso conto in seguito che l'operatore << << 'probabilmente prende comunque l'argomento per riferimento, il che rende la mia teoria completamente sbagliata. Scusate. Hai provato a registrare la classe base? Sto usando queste cose su un progetto in corso al lavoro, ma tutti i dettagli sono stati impostati da qualcun altro, quindi non sono del tutto chiaro sulla parte di installazione. :/ – aldo

+0

Ho appena provato a registrare la classe base, non ha funzionato, mi dispiace .. – CodeOrElse

0

Questo non è rigorosamente una risposta, solo una soluzione sfacciata.

Nella classe di base aggiuntivo:

virtual void StreamToArchive(boost::archive::text_oarchive &oa) = 0; 

quindi definire una STREAMTOARCHIVE macro e metterlo ad ogni una delle classi derivate.

#define STREAMTOARCHIVE void StreamToArchive(boost::archive::text_oarchive &oa) { oa << *this; } 

Poi, nel principale, sostituire

oa << base; 

con

base.StreamToArchive(oa); 

Sì lo so, è brutto, ma .. bene funziona e non mi resta che mettere che macro STREAMTOARCHIVE in le classi derivate ... Posso conviverci con questo ...

Ma poi ... per restituirlo in un oggetto, ora è un nother importa ...

Modificato: cambiato 'questo' a '* questo'

Problemi correlati