Hello everyone. I tried to serialize tree data structure.
Tree-structure's "node"-class holds "Impl"-structure and Impl-structure
holds child nodes as vector.
Problems occur when serializing a tree structure that was constructed
using above structures.
Compile errors not occur, but run-time error occures at serialization of
input-stream.
If exists someone who knows the reason of it., please teach me that.
please god bless me!
A problematic souce code has been written below and is attached on this
mail.
[Emveironment]
-Windows XP 64bit
-Visual Studio 2005 sp1
-boost-1_34_1
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BOOST_LIB_NAME boost_serialization
#include
#include
#include
#include
#include
using namespace std;
using namespace boost;
using namespace boost::serialization;
namespace test
{
class nodebase
{
public:
typedef shared_ptr<nodebase> NodePointer;
typedef vector<NodePointer> Children;
typedef Children::iterator ChildIterator;
public:
nodebase(){}
nodebase( const wstring &n ) : name(n) {}
virtual ~nodebase(){}
wstring getname() { return name; }
void setname( const wstring &newname ) { name = newname; }
private:
wstring name;
private:
friend class serialization::access;
template <class Archive>
void serialize( Archive &ar, const unsigned int version )
{
ar.register_type<nodebase>();
ar & name;
}
public:
virtual void SetParent( const NodePointer &parent ) = 0;
virtual Children GetChildren( void ) = 0;
virtual void AddChild( const NodePointer &child ) = 0;
virtual void RemoveChild( const NodePointer &child ) = 0;
virtual void Traverse( const NodePointer &root ) = 0;
};
class node : public nodebase
{
private:
struct Impl
{
Impl() {}
Impl( const Children &v ) : children(v) {}
Impl( const Children &v, const NodePointer &p ) : children(v), parent(p) {}
public:
Children children;
NodePointer parent;
private:
friend class serialization::access;
template <class Archive>
void serialize( Archive &ar, const unsigned int version )
{
ar.register_type<Impl>();
ar & children;
//ar & parent;
}
};
shared_ptr<Impl> pimpl;
public: // constructor/destructor
node() : pimpl( new Impl ) {}
node( const wstring &n ) : nodebase(n), pimpl( new Impl ) {}
node( const Children &v ) : pimpl( new Impl( v ) ) {}
node( const Children &v, const NodePointer &p ) : pimpl( new Impl( v, p
) ) {}
private: // serialization
friend class serialization::access;
template <class Archive>
void serialize( Archive &ar, const unsigned int version )
{
base_object<nodebase>(*this);
void_cast_register();
ar.register_type<node>();
ar & pimpl;
}
public: // operations
virtual void SetParent( const NodePointer &p )
{
pimpl->parent = p;
}
virtual Children GetChildren( void )
{
return pimpl->children;
}
virtual void AddChild( const NodePointer &child )
{
this->pimpl->children.push_back( child );
}
virtual void RemoveChild( const shared_ptr<nodebase> &child )
{
for( ChildIterator i = pimpl->children.begin(); i !=
pimpl->children.end(); i++ )
{
if( (*i).get() == child.get() )
{
pimpl->children.erase( i );
break;
}
}
}
virtual void Traverse( const shared_ptr<nodebase> &node )
{
if( !node )
{
return;
}
#ifdef _DEBUG
wcout << node->getname() << endl;
#endif
Children children = node->GetChildren();
for( ChildIterator i = children.begin(); i != children.end(); i++ )
{
Traverse( *i );
}
}
void print()
{
for( Children::iterator i = pimpl->children.begin(); i !=
pimpl->children.end(); i++ )
{
wcout << i->get()->getname() << endl;
}
}
};
};
BOOST_CLASS_TRACKING(test::nodebase, boost::serialization::track_always);
BOOST_CLASS_TRACKING(test::node, boost::serialization::track_always);
int _tmain(int argc, _TCHAR* argv[])
{
using namespace test;
{
node::NodePointer root( new node(wstring(L"root")) );
node::NodePointer c1( new node(wstring(L"c1")) );
node::NodePointer c2( new node(wstring(L"c2")) );
node::NodePointer c3( new node(wstring(L"c3")) );
node::NodePointer c4( new node(wstring(L"c4")) );
node::NodePointer c5( new node(wstring(L"c5")) );
c3->AddChild( c5 );
c1->AddChild( c3 );
c2->AddChild( c4 );
root->AddChild( c1 );
root->AddChild( c2 );
root->Traverse( root );
{ // output
wofstream ofile( "serialized.txt" );
try
{
archive::text_woarchive oa( ofile );
oa << (const node&)(*root);
} catch( boost::archive::archive_exception &e )
{
cout << "At the output : " << e.what() << endl;
getchar();
ofile.close();
exit(1);
}
ofile.close();
}
node::NodePointer in;
{ // input
wifstream ifile( "serialized.txt" );
try
{
archive::text_wiarchive ia( ifile );
ia >> in;
} catch( boost::archive::archive_exception &e )
{
cout << "At the input : " << e.what() << endl;
getchar();
ifile.close();
exit(e.code);
}
ifile.close();
}
}
getchar();
return 0;
}