Boost logo

Boost :

From: Anders Edin (anders.edin_at_[hidden])
Date: 2007-07-02 11:01:56


 

Hello, we have a problem when serializing weak_ptr.

 

The second example below produces invalid XML where the same attributes
appears two times with different values.

 

It appears that both save and load using boost::serialization works, but
other tools complains about the XML code being invalid.

 

The example has been tested using Boost 1.33.1 in Visual Studio 2005.

 

Anders Edin, Sidec Technologies AB

 

 

 

#include <iostream>

 

#include <boost/shared_ptr.hpp>

#include <boost/weak_ptr.hpp>

 

#include <boost/archive/xml_oarchive.hpp>

#include <boost/serialization/access.hpp>

#include <boost/serialization/version.hpp>

#include <boost/serialization/base_object.hpp>

#include <boost/serialization/shared_ptr.hpp>

#include <boost/serialization/weak_ptr.hpp>

 

class A

{

public:

    A() {}

    virtual ~A() {}

    

    virtual void set_self(boost::shared_ptr<A> s)

    {

        self_ = s;

    }

    

    virtual boost::shared_ptr<A> get_self() const

    {

        return self_.lock();

    }

 

private:

    friend boost::serialization::access;

    template <typename Archive>

    void serialize(Archive& archive, const unsigned int file_version)

    {

        archive & boost::serialization::make_nvp("self_", self_);

    }

 

    boost::weak_ptr<A> self_;

};

 

BOOST_CLASS_VERSION(A, 1);

 

class B: public A

{

public:

    B(): value_(3) {}

    virtual ~B() {}

 

private:

    friend boost::serialization::access;

    template <typename Archive>

    void serialize(Archive& archive, const unsigned int file_version)

    {

        archive & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);

        archive & boost::serialization::make_nvp("value_", value_);

    }

 

    int value_;

};

 

BOOST_CLASS_VERSION(B, 1);

 

int main(int argc, char* argv[])

{

    // First example

 

    // This test object points to itself

    boost::shared_ptr<A> a(new A());

    a->set_self(a);

    {

        boost::archive::xml_oarchive archive(std::cout);

        archive << boost::serialization::make_nvp("A", a);

    }

 

    std::cout<<std::endl;

 

 

    // Second example

 

    // This test object also points to itself, but by pointing to its
base class

    boost::shared_ptr<B> b(new B());

    b->set_self(b);

    {

        boost::archive::xml_oarchive archive(std::cout);

        archive << boost::serialization::make_nvp("B", b);

    }

 

    return 0;

}

 

/* Output from running the program in Visual Studio 2005 using boost
1.33.1

 * The first example works as expected

 * The second example produces invalid XML with attributes having two
values in self_

 

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

<!DOCTYPE boost_serialization>

<boost_serialization signature="serialization::archive" version="3">

<A class_id="0" tracking_level="0" version="1">

        <px class_id="1" tracking_level="1" version="1" object_id="_0">

                <self_ class_id="2" tracking_level="0" version="0">

                        <px class_id_reference="1"
object_id_reference="_0"></px>

                </self_>

        </px>

</A>

</boost_serialization>

 

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

<!DOCTYPE boost_serialization>

<boost_serialization signature="serialization::archive" version="3">

<B class_id="0" tracking_level="0" version="1">

        <px class_id="1" tracking_level="1" version="1" object_id="_0">

                <A class_id="2" tracking_level="1" version="1"
object_id="_1">

                        <self_ class_id="3" tracking_level="0"
version="0" class_id="4" tracking_level="0" version="1">

                                <px class_id_reference="1"
object_id_reference="_0"></px>

                        </self_>

                </A>

                <value_>3</value_>

        </px>

</B>

</boost_serialization>

 

*/

 


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk