| 1 | #include <cassert>
 | 
|---|
| 2 | #include <fstream>
 | 
|---|
| 3 | #include <boost/archive/xml_oarchive.hpp>
 | 
|---|
| 4 | #include <boost/archive/xml_iarchive.hpp>
 | 
|---|
| 5 | #include <boost/serialization/nvp.hpp>
 | 
|---|
| 6 | #include <boost/serialization/export.hpp>
 | 
|---|
| 7 | 
 | 
|---|
| 8 | #include <boost/serialization/shared_ptr.hpp>
 | 
|---|
| 9 | #include <boost/serialization/weak_ptr.hpp>
 | 
|---|
| 10 | 
 | 
|---|
| 11 | struct Base1 {
 | 
|---|
| 12 |     int m_x;
 | 
|---|
| 13 |     Base1(){}
 | 
|---|
| 14 |     Base1(int x) : m_x(1 + x) {}
 | 
|---|
| 15 |     virtual ~Base1() {}
 | 
|---|
| 16 |     bool operator==(Base1 & rhs) const {
 | 
|---|
| 17 |         return m_x == rhs.m_x;
 | 
|---|
| 18 |     }
 | 
|---|
| 19 |     // serialize
 | 
|---|
| 20 |     friend class boost::serialization::access;
 | 
|---|
| 21 |     template<class Archive>
 | 
|---|
| 22 |     void serialize(Archive & /*ar*/, const unsigned int /* file_version */) {}
 | 
|---|
| 23 | };
 | 
|---|
| 24 | 
 | 
|---|
| 25 | //BOOST_CLASS_EXPORT(Base1)
 | 
|---|
| 26 | 
 | 
|---|
| 27 | struct Base2 {
 | 
|---|
| 28 |     int m_x;
 | 
|---|
| 29 |     Base2(){}
 | 
|---|
| 30 |     Base2(int x) : m_x(2 + x) {}
 | 
|---|
| 31 |     virtual ~Base2() {}
 | 
|---|
| 32 |     bool operator==(Base2 & rhs) const {
 | 
|---|
| 33 |         return m_x == rhs.m_x;
 | 
|---|
| 34 |     }
 | 
|---|
| 35 |     // serialize
 | 
|---|
| 36 |     friend class boost::serialization::access;
 | 
|---|
| 37 |     template<class Archive>
 | 
|---|
| 38 |     void serialize(Archive & /*ar*/, const unsigned int /* file_version */) {}
 | 
|---|
| 39 | };
 | 
|---|
| 40 | 
 | 
|---|
| 41 | //BOOST_CLASS_EXPORT(Base2)
 | 
|---|
| 42 | 
 | 
|---|
| 43 | struct Sub:public Base1, public Base2 {
 | 
|---|
| 44 |     int m_x;
 | 
|---|
| 45 |     boost::weak_ptr<Sub> m_wp;
 | 
|---|
| 46 |     Sub(){}
 | 
|---|
| 47 |     Sub(int x) :
 | 
|---|
| 48 |         Base1(x),
 | 
|---|
| 49 |         Base2(x),
 | 
|---|
| 50 |         m_x(x)
 | 
|---|
| 51 |     {}
 | 
|---|
| 52 | 
 | 
|---|
| 53 | 
 | 
|---|
| 54 |     bool operator==(Sub & rhs) const {
 | 
|---|
| 55 |         if(! Base2::operator==(rhs))
 | 
|---|
| 56 |             return false;
 | 
|---|
| 57 |         if(! Base1::operator==(rhs))
 | 
|---|
| 58 |             return false;
 | 
|---|
| 59 |         return m_x == rhs.m_x;
 | 
|---|
| 60 |     }
 | 
|---|
| 61 |     virtual ~Sub() {}
 | 
|---|
| 62 | 
 | 
|---|
| 63 |     // serialize
 | 
|---|
| 64 |     friend class boost::serialization::access;
 | 
|---|
| 65 |     template<class Archive>
 | 
|---|
| 66 |     void serialize(Archive &ar, const unsigned int /* file_version */)
 | 
|---|
| 67 |     {
 | 
|---|
| 68 |         ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base1);
 | 
|---|
| 69 |         ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base2);
 | 
|---|
| 70 |         ar & BOOST_SERIALIZATION_NVP(m_x);
 | 
|---|
| 71 |         ar & BOOST_SERIALIZATION_NVP(m_wp); // *1
 | 
|---|
| 72 |     }
 | 
|---|
| 73 | };
 | 
|---|
| 74 | 
 | 
|---|
| 75 | BOOST_CLASS_EXPORT(Sub)
 | 
|---|
| 76 | 
 | 
|---|
| 77 | int main()
 | 
|---|
| 78 | {
 | 
|---|
| 79 |     boost::shared_ptr<Base2> pb2;
 | 
|---|
| 80 |     {
 | 
|---|
| 81 |         // serialize
 | 
|---|
| 82 |         boost::shared_ptr<Sub> s(new Sub(2));
 | 
|---|
| 83 |         s->m_wp = s; // set weak_ptr. If not set, deserialize success.
 | 
|---|
| 84 |         pb2 = boost::shared_ptr<Sub>(s);
 | 
|---|
| 85 |         std::ofstream ofs("output.xml");
 | 
|---|
| 86 |         assert(ofs);
 | 
|---|
| 87 |         boost::archive::xml_oarchive oa(ofs);
 | 
|---|
| 88 |         oa << boost::serialization::make_nvp("Base2", pb2);
 | 
|---|
| 89 |     }
 | 
|---|
| 90 |     boost::shared_ptr<Base2> pb2_1;
 | 
|---|
| 91 |     {
 | 
|---|
| 92 |         // de-serialize
 | 
|---|
| 93 |         std::ifstream ifs("output.xml");
 | 
|---|
| 94 |         assert(ifs);
 | 
|---|
| 95 |         boost::archive::xml_iarchive ia(ifs);
 | 
|---|
| 96 |         ia >> boost::serialization::make_nvp("Base2", pb2_1);
 | 
|---|
| 97 |     }
 | 
|---|
| 98 |     assert(*dynamic_cast<Sub *>(pb2.get()) == *dynamic_cast<Sub *>(pb2_1.get()));
 | 
|---|
| 99 | }
 | 
|---|
| 100 | 
 | 
|---|