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 |
|
---|