boost::serialization of mutual pointers
- by KneLL
First, please take a look at these code:
class Key;
class Door;
class Key
{
public:
int id;
Door *pDoor;
Key() : id(0), pDoor(NULL) {}
private:
friend class boost::serialization::access;
template <typename A>
void serialize(A &ar, const unsigned int ver)
{
ar & BOOST_SERIALIZATION_NVP(id) & BOOST_SERIALIZATION_NVP(pDoor);
}
};
class Door
{
public:
int id;
Key *pKey;
Door() : id(0), pKey(NULL) {}
private:
friend class boost::serialization::access;
template <typename A>
void serialize(A &ar, const unsigned int ver)
{
ar & BOOST_SERIALIZATION_NVP(id) & BOOST_SERIALIZATION_NVP(pKey);
}
};
BOOST_CLASS_TRACKING(Key, track_selectively);
BOOST_CLASS_TRACKING(Door, track_selectively);
int main()
{
Key k1, k_in;
Door d1, d_in;
k1.id = 1;
d1.id = 2;
k1.pDoor = &d1;
d1.pKey = &k1;
// Save data
{
wofstream f1("test.xml");
boost::archive::xml_woarchive ar1(f1);
// !!!!! (1)
const Key *pK = &k1;
const Door *pD = &d1;
ar1 << BOOST_SERIALIZATION_NVP(pK) << BOOST_SERIALIZATION_NVP(pD);
}
// Load data
{
wifstream i1("test.xml");
boost::archive::xml_wiarchive ar1(i1);
// !!!!! (2)
A *pK = &k_in;
B *pD = &d_in;
// (2.1)
//ar1 >> BOOST_SERIALIZATION_NVP(k_in) >> BOOST_SERIALIZATION_NVP(d_in);
// (2.2)
ar1 >> BOOST_SERIALIZATION_NVP(pK) >> BOOST_SERIALIZATION_NVP(pD);
}
}
The first (1) is a simple question - is it possible to pass objects to archive without pointers? If simply pass objects 'as is' that boost throws exception about duplicated pointers. But I'm confused of creating pointers to save objects.
The second (2) is a real trouble.
If comment out string after (2.1) then boost will corectly load a first Key object (and init internal Door pointer pDoor), but will not init a second Door (d_in) object. After this I have an inited *k_in* object with valid pointer to Door and empty *d_in* object.
If use string (2.2) then boost will create two Key and Door objects somewhere in memory and save addresses in pointers. But I want to have two objects *k_in* and *d_in*.
So, if I copy a values of memory objects to local variables then I store only addresses, for example, I can write code after (2.2):
d_in.id = pD->id;
d_in.pKey = pD->pKey;
But in this case I store only a pointer and memory object remains in memory and I cannot delete it, because *d_in.pKey* will be unvalid.
And I cannot perform a deep copy with operator=(), because if I write code like this:
Key &operator==(const Key &k)
{
if (this != &k)
{
id = k.id;
// call to Door::operator=() that calls *pKey = *d.pKey and so on
*pDoor = *k.pDoor;
}
return *this;
}
then I will get a something like recursion of operator=()s of Key and Door.
How to implement proper serialization of such pointers?