2010-12-13 103 views
9

J'ai lu, référencé, et finalement ne pas trouver un exemple cohérent et une réponse. Ce que j'essaie de faire est assez simple, mais il me manque clairement quelque chose. en anglais, j'ai une structure de classe avec deux bases abstraites (BB pur dérive de AA pur), que je gère comme:exception de sérialisation boost: classe non enregistrée, problème de base polymorphe sérialisant

std::vector<AA*> 

je voudrais sérialiser un autre objet contenant ce vecteur. tout sauf ce vecteur sérialise bien, mais une fois qu'il est au vecteur, il lance:

terminate called after throwing an instance of 'boost::archive::archive_exception' 
    what(): unregistered class - derived class not registered or exported 

J'ai essayé quelques choses, y compris l'enregistrement de façon explicite les types de parents avant sérialisation, déclarant expressément l'abstrait de base classes en tant que telles avec 'BOOST_SERIALIZATION_ASSUME_ABSTRACT', etc. Cependant, il me reste l'exception à l'exécution. Je voudrais obtenir cet exemple (et la solution) sur l'enregistrement afin que d'autres puissent utiliser cette bibliothèque excellente, même si elle est un peu opaque. une fois que cet exemple est carré, je le soumettrai aux responsables de la sérialisation de boost pour les inclure dans la FAQ ou dans la documentation comme bon leur semble.

exemple de code pour reproduire le problème ci-dessous:

/* 
    g++ -Iinclude/ -Llib -lboost_serialization ~/Desktop/ser_ex.cpp -o stest 
*/ 
#include <boost/serialization/serialization.hpp> 
#include <boost/serialization/nvp.hpp> 
#include <boost/archive/xml_oarchive.hpp> 
#include <boost/serialization/vector.hpp> 

#include <iostream> 
#include <fstream> 
#include <string> 
#include <vector> 

namespace bser = boost::serialization; 
class AA 
{ 
public: 
    virtual void foo() = 0; 
    std::string name; 

    template<class Archive> 
    void serialize(Archive & ar, unsigned int file_version) 
    { 
     ar & bser::make_nvp("Name", name); 
    } 
}; 
BOOST_SERIALIZATION_ASSUME_ABSTRACT(AA); 

class BB : public AA 
{ 
public: 
    virtual void foo() = 0; 
    virtual void bar() = 0; 
    int thing; 

    template<class Archive> 
    void serialize(Archive & ar, unsigned int file_version) 
    { 
     ar.template register_type<AA>(); 
     ar & bser::base_object<AA>(*this); 
     ar & bser::make_nvp("Thing", thing); 
    } 
}; 
BOOST_SERIALIZATION_ASSUME_ABSTRACT(BB); 

class CC : public BB 
{ 
public: 
    virtual void foo() {} 
    virtual void bar() {} 
    int otherThing; 

    template<class Archive> 
    void serialize(Archive & ar, unsigned int file_version) 
    { 
     ar.template register_type<BB>(); 
     ar & bser::base_object<BB>(*this); 
     ar & bser::make_nvp("OtherThing", otherThing); 
    } 
}; 

int main (int argc, char const *argv[]) 
{ 
    const std::string filename("my.serialized"); 
    const std::string key("AAVector"); 

    std::vector< AA* > vv; 
    vv.push_back(new CC); 

    std::ofstream outfilestream(filename.c_str(), std::ios::binary); 
    boost::archive::xml_oarchive out_archive(outfilestream); 
    out_archive << boost::serialization::make_nvp(key.c_str(), vv); 
    outfilestream.close(); 
} 

Répondre

6

Je suis arrivé que cela fonctionne avec des modifications mineures:

  • Remplacer ar & bser::base_object<AA>(*this); en BB::serialize avec:

    ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(AA); 
    
  • Remplacer ar & bser::base_object<BB>(*this); en CC::serialize avec:

    ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(BB); 
    
  • Ajouter un BOOST_CLASS_EXPORT(CC) après CC définition. Voir this documentation section pour une explication.