2010-08-02 23 views
5

me gustaría serializar una clase con un atributo como una lista de punteros en una clase genéricaC++ Boost serialización La serialización de clases derivadas de plantilla

Esta es la clase padre de la que la clase genérica deriva:

class Base{ 

    public : 

     friend class boost::serialization::access; 

     virtual ~Base(){} 

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

     virtual string Getid() = 0 ; 

}; 

La clase genérica:

template<typename T> 
class GenericBase : public Base 
{ 
    public: 

     friend class boost::serialization::access; 

     GenericBase<T>(string id){} 
     ~GenericBase(){} 

     string id; 

     vector<T> data 

     template<class Archive> 
     void serialize(Archive & ar, const unsigned int version) 
     { 
      ar & boost::serialization::base_object<Base>(*this); 
      ar & BOOST_SERIALIZATION_NVP(id); 
      ar & BOOST_SERIALIZATION_NVP(data); 

     } 

     string Getid() { return id; } 

}; 

La clase i desea realizar una serie

class Use 
{ 
    public: 

     friend class boost::serialization::access; 

     int Id; 

     map<string, Base*> BaseDatas; 

     Use(); 
     ~Use(); 

}; 

Así que, después de leer el documento impulso serialización (http://www.boost.org/doc/libs/1_43_0/libs/serialization/doc/serialization.html#derivedpointers), he intentado esto en el código de serialización:

main(){ 

    Use u = Use(); 

    std::ofstream ofs(filename, ios::binary); 

    // save data to archive 

    boost::archive::binary_oarchive oa(ofs); 

    oa.template register_type<GenericBase<Type1> >(); 
    oa.template register_type<GenericBase<Type2> >(); 
    oa.template register_type<GenericBase<Type3> >(); 

    oa<<u; 

} 

Tengo un mensaje,

error: 'template' (as a disambiguator) is only allowed within templates

, así que sustituí

oa.template register_type >();

por

oa.register_type();

funcionó y yo hemos sido capaces de ahorrar en el texto y en formato binario (lo he comprobado los datos básicos)

para la carga ahora, acabo de utilizar estas líneas:

main(){ 

    Use u; 

    std::ifstream ifs(filename, ios::binary); 

    // load data 

    ia.register_type<GenericBase<Type1> >(); 

    boost::archive::binary_iarchive ia(ifs); 

    ia>>u; 

} 

que me tiró un error:

error: no matching function for call to 'GenericBase::GenericBase()'

alguien me dijeron que tenía que anular 2 métodos de guardar y cargar como en esta muestra http://www.boost.org/doc/libs/1_43_0/libs/serialization/doc/serialization.html#constructors

namespace boost { namespace serialization { 
template<class Archive> 
inline void save_construct_data(
    Archive & ar, const my_class * t, const unsigned int file_version) 
    { 
     // save data required to construct instance 
     ar << t->m_attribute; 
    } 

template<class Archive> 
inline void load_construct_data(
    Archive & ar, my_class * t, const unsigned int file_version) 
    { 
     // retrieve data from archive required to construct new instance 
     int attribute; 
     ar >> attribute; 
     // invoke inplace constructor to initialize instance of my_class 
     ::new(t)my_class(attribute); 
    } 
}} // namespace ... 

pero ¿dónde tengo que definirlos? En declaración de la clase de Uso? ¿Y cómo trato con el miembro

map<string, Base*> BaseDatas; 

?

gracias por su ayuda;)

+0

¿No debería derivarse 'clase Use' de' Base' o 'GenericBase'? – Inverse

+0

No, clase El uso usa Base como un atributo – user408535

+0

La clase de uso que proporcionó le falta una función de serialización. –

Respuesta

0

but where do I have to define them ?

Puede definir en cualquiera de sus cabeceras

And how do I deal with the member...

creo que se puede conseguir impulso para realizar un seguimiento de punteros usando BOOST_CLASS_TRACKING ...

http://www.boost.org/doc/libs/1_42_0/libs/serialization/doc/special.html#objecttracking

+0

"Puede definirlos en cualquiera de sus encabezados" pero ¿en qué clase haeder? Use, Base, GenericBase? "Creo que se puede conseguir impulso para realizar un seguimiento de punteros utilizando BOOST_CLASS_TRACKING ..." cuál es el punto? el problema no es un solo puntero, sino un mapa de punteros; ¿Cómo trato este mapa de punteros en el método load_construct_data? – user408535

+0

Pongo el mío en un encabezado separado llamado "serialisation.hpp" ... que podría ser un buen lugar, luego lo incluyo en los otros encabezados de clase? El mapa se puede tratar usando la serialización integrada de algunos contenedores stl: #include "boost/serialization/map.hpp" – user274244

4

Es más fácil comentar si eres profesional vide un ejemplo de trabajo (cortar y pegar) de su código que falla, con algunos datos ficticios ...

Pero trato de responder de todos modos ...

Boost.serialisation está intentando llamar al constructor predeterminado de GenericBases, pero falla ya que no lo proporciona. Boost.serialisation primero crea su objeto (o lo intenta ahora), ENTONCES lee el archivo y establece las variables.

Puede intentar declarar un constructor predeterminado protegido, que debe tener acceso a través de acceso.

+0

guardó mi cordura, agregó un ctor protegido predeterminado y todo lo que debería haber estado funcionando comenzó a funcionar. .. – mentat

Cuestiones relacionadas