|
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