boost::serialization of mutual pointers

Posted by KneLL on Stack Overflow See other posts from Stack Overflow or by KneLL
Published on 2010-04-02T12:37:08Z Indexed on 2010/04/02 12:43 UTC
Read the original article Hit count: 422

Filed under:
|
|

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?

© Stack Overflow or respective owner

Related posts about boost

Related posts about serialization