| 1 | #include <cassert>
|
|---|
| 2 | #include <fstream>
|
|---|
| 3 |
|
|---|
| 4 | #include <boost/shared_ptr.hpp>
|
|---|
| 5 | #include <boost/weak_ptr.hpp>
|
|---|
| 6 |
|
|---|
| 7 | #include <boost/serialization/serialization.hpp>
|
|---|
| 8 |
|
|---|
| 9 | #include <boost/archive/xml_oarchive.hpp>
|
|---|
| 10 | #include <boost/archive/xml_iarchive.hpp>
|
|---|
| 11 | #include <boost/serialization/nvp.hpp>
|
|---|
| 12 |
|
|---|
| 13 | #include <boost/serialization/export.hpp>
|
|---|
| 14 |
|
|---|
| 15 | #include <boost/serialization/shared_ptr.hpp>
|
|---|
| 16 | #include <boost/serialization/weak_ptr.hpp>
|
|---|
| 17 |
|
|---|
| 18 | class Left;
|
|---|
| 19 | typedef boost::shared_ptr<Left> LeftSp;
|
|---|
| 20 |
|
|---|
| 21 | class Right;
|
|---|
| 22 | typedef boost::shared_ptr<Right> RightSp;
|
|---|
| 23 |
|
|---|
| 24 | class Bottom;
|
|---|
| 25 | typedef boost::shared_ptr<Bottom> BottomSp;
|
|---|
| 26 | typedef boost::weak_ptr<Bottom> BottomWp;
|
|---|
| 27 |
|
|---|
| 28 | class Left {
|
|---|
| 29 | public:
|
|---|
| 30 | Left() {}
|
|---|
| 31 | virtual ~Left() {}
|
|---|
| 32 | private:
|
|---|
| 33 | // serialize
|
|---|
| 34 | friend class boost::serialization::access;
|
|---|
| 35 | template<class Archive>
|
|---|
| 36 | void serialize(Archive & /*ar*/, const unsigned int /* file_version */) {}
|
|---|
| 37 | };
|
|---|
| 38 |
|
|---|
| 39 | BOOST_CLASS_EXPORT(Left)
|
|---|
| 40 |
|
|---|
| 41 | class Right {
|
|---|
| 42 | public:
|
|---|
| 43 | Right() {}
|
|---|
| 44 | virtual ~Right() {}
|
|---|
| 45 | private:
|
|---|
| 46 | // serialize
|
|---|
| 47 | friend class boost::serialization::access;
|
|---|
| 48 | template<class Archive>
|
|---|
| 49 | void serialize(Archive & /*ar*/, const unsigned int /* file_version */) {}
|
|---|
| 50 | };
|
|---|
| 51 |
|
|---|
| 52 | BOOST_CLASS_EXPORT(Right)
|
|---|
| 53 |
|
|---|
| 54 | class Bottom:public Left, public Right {
|
|---|
| 55 | public:
|
|---|
| 56 | virtual ~Bottom() {}
|
|---|
| 57 | static BottomSp create()
|
|---|
| 58 | {
|
|---|
| 59 | BottomSp sp(new Bottom);
|
|---|
| 60 | sp->setWp(sp);
|
|---|
| 61 | return sp;
|
|---|
| 62 | }
|
|---|
| 63 | private:
|
|---|
| 64 | BottomWp wp_;
|
|---|
| 65 |
|
|---|
| 66 | Bottom() {}
|
|---|
| 67 | void setWp(BottomSp sp) { wp_ = sp; }
|
|---|
| 68 |
|
|---|
| 69 | // serialize
|
|---|
| 70 | friend class boost::serialization::access;
|
|---|
| 71 | template<class Archive>
|
|---|
| 72 | void save(Archive &ar, const unsigned int /* file_version */) const
|
|---|
| 73 | {
|
|---|
| 74 | ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(Left);
|
|---|
| 75 | ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(Right);
|
|---|
| 76 | ar << BOOST_SERIALIZATION_NVP(wp_); // *1
|
|---|
| 77 | }
|
|---|
| 78 | template<class Archive>
|
|---|
| 79 | void load(Archive & ar, const unsigned int /* file_version */)
|
|---|
| 80 | {
|
|---|
| 81 | ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(Left);
|
|---|
| 82 | ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(Right);
|
|---|
| 83 | ar >> BOOST_SERIALIZATION_NVP(wp_); // *2
|
|---|
| 84 | }
|
|---|
| 85 | BOOST_SERIALIZATION_SPLIT_MEMBER()
|
|---|
| 86 | };
|
|---|
| 87 |
|
|---|
| 88 | BOOST_CLASS_EXPORT(Bottom)
|
|---|
| 89 |
|
|---|
| 90 | class Holder {
|
|---|
| 91 | public:
|
|---|
| 92 | LeftSp mbl_; // shared_ptr<Left>
|
|---|
| 93 | RightSp mbr_; // shared_ptr<Right>
|
|---|
| 94 |
|
|---|
| 95 | Holder() {} // for serialize
|
|---|
| 96 | Holder(BottomSp l, BottomSp r):mbl_(l) ,mbr_(r) {} // for appli construct
|
|---|
| 97 |
|
|---|
| 98 | // serialize
|
|---|
| 99 | friend class boost::serialization::access;
|
|---|
| 100 | template<class Archive>
|
|---|
| 101 | void save(Archive &ar, const unsigned int /* file_version */) const
|
|---|
| 102 | {
|
|---|
| 103 | // polymophic serialize via shared_ptr
|
|---|
| 104 | ar << BOOST_SERIALIZATION_NVP(mbl_);
|
|---|
| 105 | // polymophic serialize via shared_ptr
|
|---|
| 106 | ar << BOOST_SERIALIZATION_NVP(mbr_);
|
|---|
| 107 | }
|
|---|
| 108 | template<class Archive>
|
|---|
| 109 | void load(Archive & ar, const unsigned int /* file_version */)
|
|---|
| 110 | {
|
|---|
| 111 | // polymophic de-serialize via shared_ptr
|
|---|
| 112 | ar >> BOOST_SERIALIZATION_NVP(mbl_);
|
|---|
| 113 | // polymophic de-serialize via shared_ptr
|
|---|
| 114 | ar >> BOOST_SERIALIZATION_NVP(mbr_);
|
|---|
| 115 | }
|
|---|
| 116 | BOOST_SERIALIZATION_SPLIT_MEMBER()
|
|---|
| 117 | };
|
|---|
| 118 |
|
|---|
| 119 | BOOST_CLASS_EXPORT(Holder)
|
|---|
| 120 |
|
|---|
| 121 | int main()
|
|---|
| 122 | {
|
|---|
| 123 |
|
|---|
| 124 | {
|
|---|
| 125 | // serialize
|
|---|
| 126 | Holder h1(Bottom::create(), Bottom::create());
|
|---|
| 127 | std::ofstream ofs("output.xml");
|
|---|
| 128 | assert(ofs);
|
|---|
| 129 | boost::archive::xml_oarchive oa(ofs);
|
|---|
| 130 | oa << boost::serialization::make_nvp("Holder", h1);
|
|---|
| 131 | }
|
|---|
| 132 | {
|
|---|
| 133 | // de-serialize
|
|---|
| 134 | Holder h2;
|
|---|
| 135 | std::ifstream ifs("output.xml");
|
|---|
| 136 | assert(ifs);
|
|---|
| 137 | boost::archive::xml_iarchive ia(ifs);
|
|---|
| 138 | ia >> boost::serialization::make_nvp("Holder", h2);
|
|---|
| 139 |
|
|---|
| 140 | // check
|
|---|
| 141 | Left *pLeft = h2.mbl_.get();
|
|---|
| 142 | Bottom *pBottomFromLeft = dynamic_cast<Bottom *>(pLeft);
|
|---|
| 143 |
|
|---|
| 144 | Right *pRight = h2.mbr_.get();
|
|---|
| 145 | Bottom *pBottomFromRight = dynamic_cast<Bottom *>(pRight);
|
|---|
| 146 |
|
|---|
| 147 | assert(pBottomFromLeft); // Success
|
|---|
| 148 | assert(pBottomFromRight); // Fail. Comment out *1 and *2, it works corrctly.
|
|---|
| 149 | }
|
|---|
| 150 | }
|
|---|
| 151 |
|
|---|
| 152 | // output.xml
|
|---|
| 153 | //
|
|---|
| 154 | // <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
|---|
| 155 | // <!DOCTYPE boost_serialization>
|
|---|
| 156 | // <boost_serialization signature="serialization::archive" version="5">
|
|---|
| 157 | // <Holder class_id="0" tracking_level="1" version="0" object_id="_0">
|
|---|
| 158 | // <mbl_ class_id="1" tracking_level="0" version="1">
|
|---|
| 159 | // <px class_id="3" class_name="Bottom" tracking_level="1" version="0" object_id="_1">
|
|---|
| 160 | // <Left class_id="2" tracking_level="1" version="0" object_id="_2"></Left>
|
|---|
| 161 | // <Right class_id="4" tracking_level="1" version="0" object_id="_3"></Right>
|
|---|
| 162 | // <wp_ class_id="5" tracking_level="0" version="0">
|
|---|
| 163 | // <shared_ptr class_id="6" tracking_level="0" version="1">
|
|---|
| 164 | // <px class_id_reference="3" object_id_reference="_1"></px>
|
|---|
| 165 | // </shared_ptr>
|
|---|
| 166 | // </wp_>
|
|---|
| 167 | // </px>
|
|---|
| 168 | // </mbl_>
|
|---|
| 169 | // <mbr_ class_id="7" tracking_level="0" version="1">
|
|---|
| 170 | // <px class_id_reference="3" object_id="_4">
|
|---|
| 171 | // <Left object_id="_5"></Left>
|
|---|
| 172 | // <Right object_id="_6"></Right>
|
|---|
| 173 | // <wp_>
|
|---|
| 174 | // <shared_ptr>
|
|---|
| 175 | // <px class_id_reference="3" object_id_reference="_4"></px>
|
|---|
| 176 | // </shared_ptr>
|
|---|
| 177 | // </wp_>
|
|---|
| 178 | // </px>
|
|---|
| 179 | // </mbr_>
|
|---|
| 180 | // </Holder>
|
|---|
| 181 | // </boost_serialization>
|
|---|
| 182 |
|
|---|