2010-07-23 3 views
3

Je dois sérialisation libkdtree ++ dans mon programme, les structures d'arbres sont brièvement décrits comme suit:structure arborescente de sérialisation en utilisant boost :: sérialisation

struct _Node_base { 
    _Node_base * _M_parent, *_M_left, * _M_right; 

    template<Archive> 
    serialize(Archive &ar, const unsigned int version) { 
    ar & _M_left & _M_right; 
    } 
} 

template<typename V> 
struct _Node : public _Node_base { 
    typedef V value_type; 
    value_type value; 
    template<Archive> 
    serialize(Archive &ar, const unsigned int version) { 
    ar.register_type(static_cast<_Node*>(NULL)); 
    ar & boost::serialization::base_object<_Node_base>(*this); 
    ar & value; 
    } 
} 

struct Tree { 
    _Node * root; 
    template<Archive> 
    serialize(Archive &ar, const unsigned int version) { 
    ar & root; 
    } 
} 

Ce rapport du programme « erreur de flux ». Mais à partir du fichier "serailzed", il manque les champs de valeur pour les nœuds enfants des racines. Donc je pense qu'il est possible que BaseNode sérialisé _M_left et _M_right pointeur. Cependant, puisque _Node_base n'a aucune idée du type de valeur de _Node, il semble difficile d'ajouter "ar.register_type" à _Node_base.serialize().

+0

Ce code ne compile pas. 'Node' devrait être sous-classe' BaseNode', 'left' et' right' devrait être ptrs, 'value_type' non déclaré,' serialize' manquer le type de retour, etc etc S'il vous plaît poster un vrai code (qui compile). –

Répondre

0

La solution suivante pour libkdtree ++ & boost :: sérialisation semble travail:

// KDTree::_Node 
friend class boost::serialization::access; 
template<class Archive> 
//void serialize(Archive & ar, const unsigned int version) 
void save(Archive & ar, const unsigned int version) const 
{ 
    ar.register_type(static_cast< _Link_type>(NULL)); 
    ar & boost::serialization::base_object<_Node_base>(*this); 
    _Link_type left = static_cast<_Link_type>(_M_left); 
    _Link_type right = static_cast<_Link_type>(_M_right); 
    ar & left & right; 
    ar & _M_value; 
} 


template<class Archive> 
void load(Archive & ar, const unsigned int version) 
{ 
    ar.register_type(static_cast< _Link_type>(NULL)); 
    ar & boost::serialization::base_object<_Node_base>(*this); 
    _Link_type left, right; 
    ar & left & right; 
    ar & _M_value; 
    if (left) { 
     left->_M_parent = this; 
    } 
    if (right) { 
     right->_M_parent = this; 
    } 
    _M_left = left; 
    _M_right = right; 
} 

BOOST_SERIALIZATION_SPLIT_MEMBER() 
+0

ma solution sur http://github.com/eddyxu/kdtree-serialization – eddyxu

0

L'exception pointer_conflict documentation états (sic):

pointer_conflict, // an attempt has been made to directly 
         // serialization::detail an object 
         // after having already serialzed the same 
         // object through a pointer. Were this permited, 
         // it the archive load would result in the 
         // creation of an extra copy of the obect. 

je pense que le conflit se produit lorsque chaque est sérialisé par un ptr en BaseNode::serialize et via l'objet direct, l'expression *Node, dans Node::serialize. Cependant puisque la fonction base_object prend une référence et non un ptr, je ne suis pas sûr de savoir comment éviter cela. Une possibilité est de ne pas sérialiser le parent ptr. Au lieu de cela, après la désérialisation, effectuez une marche de l'arbre et corrigez les ptrs parents pour qu'ils pointent vers le nœud parent. Par exemple. ajoutez la méthode suivante pour BaseNode:

void fix (BaseNode* parent = 0) 
{ 
    this->parent = parent; 
    if (left != 0) 
     left->fix (this); 
    if (right != 0) 
     right->fix (this); 
} 

Ensuite il suffit d'appeler root->fix()

+0

Il a toujours une erreur de flux soulevée du processus de décodage ... Je le pense – eddyxu

+0

friend class boost :: serialization :: access; modèle serialize vide (Archive & ar, const version non signée int) { // sérialisation des informations de classe de base ar.register_type (static_cast <_Node*> (NULL)); ar & boost :: serialization :: base_object <_Node_base> (* ceci); ar & _M_value; } J'ai ajouté cette fonction dans libkdtree :: _ Node, cependant, je pense que le problème ici est la fonction serialize() dans base_object ne sérialiserait pas le _left, _right point correctement, qui les traite comme _Node_base * pointeur – eddyxu

Questions connexes