]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/serialization/doc/serialization.html
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / serialization / doc / serialization.html
1 <!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2 <html>
3 <!--
4 (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
5 Use, modification and distribution is subject to the Boost Software
6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 http://www.boost.org/LICENSE_1_0.txt)
8 -->
9 <head>
10 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
11 <link rel="stylesheet" type="text/css" href="../../../boost.css">
12 <link rel="stylesheet" type="text/css" href="style.css">
13 <title>Serialization - Serialization of Classes</title>
14 </head>
15 <body link="#0000ff" vlink="#800080">
16 <table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
17 <tr>
18 <td valign="top" width="300">
19 <h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
20 </td>
21 <td valign="top">
22 <h1 align="center">Serialization</h1>
23 <h2 align="center">Serializable Concept</h2>
24 </td>
25 </tr>
26 </table>
27 <hr>
28 <dl class="page-index">
29 <dt><a href="#primitiveoperators">Primitive Types</a>
30 <dt><a href="#classoperators">Class Types</a>
31 <dl class="page-index">
32 <dt><a href="#member">Member Function</a>
33 <dt><a href="#free">Free Function</a>
34 <dl class="page-index">
35 <dt><a href="#namespaces">Namespaces for Free Function Overrides</a>
36 </dl>
37 <dt><a href="#classmembers">Class Members</a>
38 <dl class="page-index">
39 <dt><a href="#base">Base Classes</a>
40 <dt><a href="#const"><code style="white-space: normal">const</code> Members</a>
41 <dt><a href="#templates">Templates</a>
42 </dl>
43 <dt><a href="#versioning">Versioning</a>
44 <dt><a href="#splitting">Splitting <code style="white-space: normal">serialize</code> into
45 <code style="white-space: normal">save/load</code></a>
46 <dl class="page-index">
47 <dt><a href="#splittingmemberfunctions">Member Functions</a>
48 <dt><a href="#splittingfreefunctions">Free Functions</a>
49 </dl>
50 </dl>
51 <dt><a href="#pointeroperators">Pointers</a>
52 <dl class="page-index">
53 <dt><a href="#constructors">Non-Default Constructors</a>
54 <dt><a href="#derivedpointers">Pointers to Objects of Derived Classes</a>
55 <dl class="page-index">
56 <dt><a href="#registration">Registration</a>
57 <dt><a href="#export">Export</a>
58 <dt><a href="#instantiation">Instantiation</a>
59 <dt><a href="#selectivetracking">Selective Tracking</a>
60 <dt><a href="#runtimecasting">Runtime Casting</a>
61 </dl>
62 </dl>
63 <dt><a href="#references">References</a>
64 <dt><a href="#arrays">Arrays</a>
65 <dt><a href="traits.html">Class Serialization Traits</a>
66 <dt><a href="wrappers.html">Serialization Wrappers</a>
67 <dt><a href="#models">Models - Serialization Implementations Included in the Library</a>
68 </dl>
69
70 A type <code style="white-space: normal">T</code> is <strong>Serializable</strong>
71 if and only if one of the following is true:
72 <ul>
73 <li>it is a primitive type.<br>
74 By <i>primitive type</i> we mean a C++ built-in type and <i>ONLY</i>
75 a C++ built-in type. Arithmetic (including characters), bool, enum are primitive types.
76 Below in <a target="detail" href="traits.html#Traits">serialization traits</a>,
77 we define a "primitive" implementation level in a different way for a
78 different purpose. This can be a source of confusion.
79 <li>It is a class type and one of the following has been declared according
80 to the prototypes detailed below:
81 <ul>
82 <li>a class member function <code style="white-space: normal">serialize</code>
83 <li>a global function <code style="white-space: normal">serialize</code>
84 </ul>
85 <li>it is a pointer to a <strong>Serializable</strong> type.
86 <li>it is a reference to a <strong>Serializable</strong> type.
87 <li>it is a native C++ Array of <strong>Serializable</strong> type.
88 </ul>
89
90 <h2><a name="primitiveoperators">Primitive Types</a></h2>
91 The template operators &amp;, &lt;&lt;, and &gt;&gt; of the archive classes
92 described above will generate code to save/load all primitive types
93 to/from an archive. This code will usually just add the
94 data to the archive according to the archive format.
95 For example, a four byte integer is appended to a binary archive
96 as 4 binary bytes while a to a text archive it would be
97 rendered as a space followed by a string representation.
98
99 <h2><a name="classoperators">Class Types</a></h2>
100 For class/struct types, the template operators &amp;, &lt;&lt;, and &gt;&gt;
101 will generate code that invokes the programmer's serialization code for the
102 particular data type. There is no default. An attempt to serialize a
103 class/struct for which no serialization has been explicitly specified
104 will result in a compile time error. The serialiation of a class can
105 be specified via either a class member function or a free funcation which
106 takes a reference to an instance of the class as an argument.
107
108 <h3><a name="member">Member Function</a></h3>
109 The serialization library invokes the following code to save or load a class instance
110 to/from and archive.
111 <pre><code>
112 template&lt;class Archive, class T&gt;
113 inline void serialize(
114 Archive &amp; ar,
115 T &amp; t,
116 const unsigned int file_version
117 ){
118 // invoke member function for class T
119 t.serialize(ar, file_version);
120 }
121 </code></pre>
122 That is, the default definition of template <code style="white-space: normal">serialize</code>
123 presumes the existence of a class member function template of the following
124 signature:
125 <pre><code>
126 template&lt;class Archive&gt;
127 void serialize(Archive &amp;ar, const unsigned int version){
128 ...
129 }
130 </code></pre>
131 If such a member function is not declared, a compile time error will occur. In order
132 that the member function generated by this template can be called to
133 append the data to an archive, it either must be public or the class must
134 be made accessible to the serialization library by including:
135 <pre><code>
136 friend class boost::serialization::access;
137 </code></pre>
138 in the class definition. This latter method should be preferred over the option
139 of making the member function public. This will prevent serialization functions from
140 being called from outside the library. This is almost certainly an error. Unfortunately,
141 it may appear to function but fail in a way that is very difficult to find.
142 <p>
143 It may not be immediately obvious how this one template serves for both
144 saving data to an archive as well as loading data from the archive.
145 The key is that the <code style="white-space: normal">&amp;</code> operator is
146 defined as <code style="white-space: normal">&lt;&lt;</code>
147 for output archives and as <code style="white-space: normal">&gt;&gt;</code> input archives. The
148 "polymorphic" behavior of the <code style="white-space: normal">&amp;</code> permits the same template
149 to be used for both save and load operations. This is very convenient in that it
150 saves a lot of typing and guarantees that the saving and loading of class
151 data members are always in sync. This is the key to the whole serialization
152 system.
153
154 <h3><a name="free">Free Function</a></h3>
155 Of course we're not restricted to using the default implementation described
156 above. We can override the default one with our own. Doing this will
157 permit us to implement serialization of a class without altering
158 the class definition itself. We call this <strong>non-intrusive</strong>
159 serialization. Suppose our class is named <code style="white-space: normal">my_class</code>, the
160 override would be specified as:
161 <pre><code>
162 // namespace selection
163
164 template&lt;class Archive&gt;
165 inline void serialize(
166 Archive &amp; ar,
167 my_class &amp; t,
168 const unsigned int file_version
169 ){
170 ...
171 }
172 </code></pre>
173
174 Note that we have called this override "non-intrusive". This is slightly
175 inaccurate. It does not require that the class have special functions, that
176 it be derived from some common base class or any other fundamental design changes.
177 However, it will require access to the class members that are to
178 be saved and loaded. If these members are <code style="white-space: normal">private</code>, it won't be
179 possible to serialize them. So in some instances, minor modifications to the
180 class to be serialized will be necessary even when using this "non-intrusive"
181 method. In practice this may not be such a problem as many libraries
182 (E.G. STL) expose enough information to permit implementation of non-intrusive
183 serialization with absolutly no changes to the library.
184
185 <h4><a name="namespaces">Namespaces for Free Function Overrides</a></h4>
186 For maximum portability, include any free functions templates and definitions in the
187 namespace <code style="white-space: normal">boost::serialization</code>. If portability is not a concern and the
188 compiler being used supports ADL (Argument Dependent Lookup) the free functions and
189 templates can be in any of the following namespaces:
190 <ul>
191 <li><code style="white-space: normal">boost::serialization</code>
192 <li>namespace of the archive class
193 <li>namespace of the type being serialized
194 </ul>
195 <p>
196 Note that, at first glance, this suggestion may seem to be wrong for compilers which implement
197 two phase lookup. In fact, the serialization library used a perhaps overly clever
198 method to support this rule even for such compilers. Those with an interest in studying
199 this further will find more information in
200 <a target=serialization_hpp href="../../../boost/serialization/serialization.hpp">serialization.hpp</a>
201
202 <h3><a name="classmembers">Serialization of Class Members</a></h3>
203 Regardless of which of the above methods is used, the body of the serialize function must
204 specify the data to be saved/loaded by sequential application of the archive
205 <code style="white-space: normal">operator &amp;</code> to all the data members of the class.
206 <pre><code>
207 {
208 // save/load class member variables
209 ar &amp; member1;
210 ar &amp; member2;
211 }
212 </code></pre>
213
214 <h4><a name="base">Base Classes</a></h4>
215 The header file
216 <a href="../../../boost/serialization/base_object.hpp" target="base_object_hpp">
217 base_object.hpp
218 </a>
219 includes the template:
220 <pre><code>
221 template&lt;class Base, class Derived&gt;
222 Base & base_object(Derived &d);
223 </code></pre>
224 which should be used to create a reference to an object of the base
225 which can be used as an argument to the archive serialization operators.
226 So for a class of <strong>Serializable</strong> type
227 <code style="white-space: normal">T</code> the base class state should be
228 serialized like this:
229 <pre><code>
230 {
231 // invoke serialization of the base class
232 ar &amp; boost::serialization::base_object&lt;base_class_of_T&gt;(*this);
233 // save/load class member variables
234 ar &amp; member1;
235 ar &amp; member2;
236 }
237 </code></pre>
238 Resist the temptation to just cast <code style="white-space: normal">*this</code> to the base class.
239 This might seem to work but may fail to invoke code necessary for
240 proper serialization.
241 <p>
242 Note that this is <strong>NOT</strong> the same as calling the <code style="white-space: normal">serialize</code>
243 function of the base class. This might seem to work but will circumvent
244 certain code used for tracking of objects, and registering base-derived
245 relationships and other bookkeeping that is required for the serialization
246 system to function as designed. For this reason, all <code style="white-space: normal">serialize</code>
247 member functions should be <code style="white-space: normal">private</code>.
248
249 <h4><a name="const"><code style="white-space: normal">const</code> Members</a></h4>
250 Saving <code style="white-space: normal">const</code> members to an archive
251 requires no special considerations.
252 Loading <code style="white-space: normal">const</code> members can be addressed by using a
253 <code style="white-space: normal">const_cast</code>:
254 <pre><code>
255 ar &amp; const_cast&lt;T &amp;&gt;(t);
256 </code></pre>
257 Note that this violates the spirit and intention of the <code style="white-space: normal">const</code>
258 keyword. <code style="white-space: normal">const</code> members are intialized when a class instance
259 is constructed and not changed thereafter. However, this may
260 be most appropriate in many cases. Ultimately, it comes down to
261 the question about what <code style="white-space: normal">const</code> means in the context
262 of serialization.
263
264 <h4><a name="templates"></a>Templates</h4>
265 Implementation of serialization for templates is exactly the same process
266 as for normal classes and requires no additional considerations. Among
267 other things, this implies that serialization of compositions of templates
268 are automatically generated when required if serialization of the
269 component templates is defined. For example, this library includes
270 definition of serialization for <code style="white-space: normal">boost::shared_ptr&lt;T&gt;</code> and for
271 <code style="white-space: normal">std::list&lt;T&gt;</code>. If I have defined serialization for my own
272 class <code style="white-space: normal">my_t</code>, then serialization for
273 <code style="white-space: normal">std::list&lt; boost::shared_ptr&lt; my_t&gt; &gt;</code> is already available
274 for use.
275 <p>
276 For an example that shows how this idea might be implemented for your own
277 class templates, see
278 <a href="../example/demo_auto_ptr.cpp" target="demo_auto_ptr.cpp">
279 demo_auto_ptr.cpp</a>.
280 This shows how non-intrusive serialization
281 for the template <code style="white-space: normal">auto_ptr</code> from the standard library
282 can be implemented.
283 <p>
284 A somewhat trickier addition of serialization to a standard template
285 can be found in the example
286 <a href="../../../boost/serialization/shared_ptr.hpp" target="shared_ptr_hpp">
287 shared_ptr.hpp
288 </a>
289 <!--
290 Only the most minimal change to
291 <code>shared_count.hpp</code>
292 (to gain access to some private members) was necessary to achieve this.
293 This should demonstrate how easy it is to non-intrusively
294 implement serialization to any data type or template.
295 -->
296 <p>
297 In the specification of serialization for templates, its common
298 to split <code style="white-space: normal">serialize</code>
299 into a <code style="white-space: normal">load/save</code> pair.
300 Note that the convenience macro described
301 <a href="#BOOST_SERIALIZATION_SPLIT_FREE">above</a>
302 isn't helpful in these cases as the number and kind of
303 template class arguments won't match those used when splitting
304 <code style="white-space: normal">serialize</code> for a simple class. Use the override
305 syntax instead.
306
307 <h3><a name="versioning">Versioning</a></h3>
308 It will eventually occur that class definitions change after archives have
309 been created. When a class instance is saved, the current version
310 in included in the class information stored in the archive. When the class instance
311 is loaded from the archive, the original version number is passed as an
312 argument to the loading function. This permits the load function to include
313 logic to accommodate older definitions for the class and reconcile them
314 with latest version. Save functions always save the current version. So this
315 results in automatically converting older format archives to the newest versions.
316 Version numbers are maintained independently for each class. This results in
317 a simple system for permitting access to older files and conversion of same.
318 The current version of the class is assigned as a
319 <a href="traits.html">Class Serialization Trait</a> described later in this manual.
320 <pre><code>
321 {
322 // invoke serialization of the base class
323 ar &amp; boost::serialization::base_object&lt;base_class_of_T&gt;(*this);
324 // save/load class member variables
325 ar &amp; member1;
326 ar &amp; member2;
327 // if its a recent version of the class
328 if(1 &lt; file_version)
329 // save load recently added class members
330 ar &amp; member3;
331 }
332 </code></pre>
333
334 <h3><a name="splitting">Splitting <code style="white-space: normal">serialize</code> into Save/Load</a></h3>
335 There are times when it is inconvenient to use the same
336 template for both save and load functions. For example, this might occur if versioning
337 gets complex.
338
339 <h4><a name="splittingmemberfunctions">Splitting Member Functions</a></h4>
340 For member functions this can be addressed by including
341 the header file <a href="../../../boost/serialization/split_member.hpp" target="split_member_hpp">
342 boost/serialization/split_member.hpp</a> including code like this in the class:
343 <pre><code>
344 template&lt;class Archive&gt;
345 void save(Archive &amp; ar, const unsigned int version) const
346 {
347 // invoke serialization of the base class
348 ar &lt;&lt; boost::serialization::base_object&lt;const base_class_of_T&gt;(*this);
349 ar &lt;&lt; member1;
350 ar &lt;&lt; member2;
351 ar &lt;&lt; member3;
352 }
353
354 template&lt;class Archive&gt;
355 void load(Archive &amp; ar, const unsigned int version)
356 {
357 // invoke serialization of the base class
358 ar &gt;&gt; boost::serialization::base_object&lt;base_class_of_T&gt;(*this);
359 ar &gt;&gt; member1;
360 ar &gt;&gt; member2;
361 if(version &gt; 0)
362 ar &gt;&gt; member3;
363 }
364
365 template&lt;class Archive&gt;
366 void serialize(
367 Archive &amp; ar,
368 const unsigned int file_version
369 ){
370 boost::serialization::split_member(ar, *this, file_version);
371 }
372 </code></pre>
373 This splits the serialization into two separate functions <code style="white-space: normal">save</code>
374 and <code style="white-space: normal">load</code>. Since the new <code style="white-space: normal">serialize</code> template
375 is always the same it can be generated by invoking the macro
376 BOOST_SERIALIZATION_SPLIT_MEMBER() defined in the header file
377 <a href="../../../boost/serialization/split_member.hpp" target="split_member_hpp">
378 boost/serialization/split_member.hpp
379 </a>.
380 So the entire <code style="white-space: normal">serialize</code> function above can be replaced with:
381 <pre><code>
382 BOOST_SERIALIZATION_SPLIT_MEMBER()
383 </code></pre>
384 <h4><a name="splittingfreefunctions">Splitting Free Functions</a></h4>
385 The situation is same for non-intrusive serialization with the free
386 <code style="white-space: normal">serialize</code> function template.
387
388 <a name="BOOST_SERIALIZATION_SPLIT_FREE">
389 To use <code style="white-space: normal">save</code> and
390 <code style="white-space: normal">load</code> function templates rather than
391 <code style="white-space: normal">serialize</code>:
392 <pre><code>
393 namespace boost { namespace serialization {
394 template&lt;class Archive&gt;
395 void save(Archive &amp; ar, const my_class &amp; t, unsigned int version)
396 {
397 ...
398 }
399 template&lt;class Archive&gt;
400 void load(Archive &amp; ar, my_class &amp; t, unsigned int version)
401 {
402 ...
403 }
404 }}
405 </code></pre>
406 include the header file
407 <a href="../../../boost/serialization/split_free.hpp" target="split_free_hpp">
408 boost/serialization/split_free.hpp
409 </a>.
410 and override the free <code style="white-space: normal">serialize</code> function template:
411 <pre><code>
412 namespace boost { namespace serialization {
413 template&lt;class Archive&gt;
414 inline void serialize(
415 Archive &amp; ar,
416 my_class &amp; t,
417 const unsigned int file_version
418 ){
419 split_free(ar, t, file_version);
420 }
421 }}
422 </code></pre>
423 To shorten typing, the above template can be replaced with
424 the macro:
425 <pre><code>
426 BOOST_SERIALIZATION_SPLIT_FREE(my_class)
427 </code></pre>
428
429 Note that although the functionality to split the <code style="white-space: normal">
430 serialize</code> function into <code style="white-space: normal">save/load</code>
431 has been provided, the usage of the <code style="white-space: normal">serialize</code>
432 function with the corresponding <code style="white-space: normal">&amp;</code> operator
433 is preferred. The key to the serialization implementation is that objects are saved
434 and loaded in exactly the same sequence. Using the <code style="white-space: normal">&amp;</code>
435 operator and <code style="white-space: normal">serialize</code>
436 function guarantees that this is always the case and will minimize the
437 occurrence of hard to find errors related to synchronization of
438 <code style="white-space: normal">save</code> and <code style="white-space: normal">load</code>
439 functions.
440 <p>
441 Also note that <code style="white-space: normal">BOOST_SERIALIZATION_SPLIT_FREE</code>
442 must be used outside of any namespace.
443
444 <h2><a name="pointeroperators">Pointers</a></h2>
445 A pointer to any class instance can be serialized with any of the archive
446 save/load operators.
447 <p>
448 To properly save and restore an object through a pointer the
449 following situations must be addressed:
450 <ol>
451 <li>If the same object is saved multiple times through different
452 pointers, only one copy of the object need be saved.
453 <li>If an object is loaded multiple times through different pointers,
454 only one new object should be created and all returned pointers
455 should point to it.
456 <li>The system must detect the case where an object is first
457 saved through a pointer then the object itself is saved.
458 Without taking extra precautions, loading would result in the
459 creation of multiple copies of the original object. This system detects
460 this case when saving and throws an exception - see below.
461 <li>An object of a derived class may be stored through a
462 pointer to the base class. The true type of the object must
463 be determined and saved. Upon restoration the correct type
464 must be created and its address correctly cast to the base
465 class. That is, polymorphic pointers have to be considered.
466 <li>NULL pointers must be dectected when saved and restored
467 to NULL when deserialized.
468 </ol>
469
470 This serialization library addresses all of the above
471 considerations. The process of saving and loading an object
472 through a pointer is non-trivial. It can be summarized as
473 follows:
474 <p>Saving a pointer:
475 <ol>
476 <li>determine the true type of the object being pointed to.
477 <li>write a special tag to the archive
478 <li>if the object pointed to has not already been written
479 to the archive, do so now
480 </ol>
481 Loading a pointer:
482 <ol>
483 <li>read a tag from the archive.
484 <li>determine the type of object to be created
485 <li>if the object has already been loaded, return its address.
486 <li>otherwise, create a new instance of the object
487 <li>read the data back in using the operators described above
488 <li>return the address of the newly created object.
489 </ol>
490
491 Given that class instances are saved/loaded to/from the archive
492 only once, regardless of how many times they are serialized with
493 the <code style="white-space: normal">&lt;&lt;</code>
494 and <code style="white-space: normal">&gt;&gt;</code> operators
495 <ul>
496 <li>Loading the same pointer object multiple times
497 results in only one object being created, thereby replicating
498 the original pointer configuration.
499 <li>Structures, such as collections of polymorphic pointers,
500 are handled with no special effort on the part of users of this library.
501 </ul>
502 Serialization of pointers of derived types through a pointer to the
503 base class may require a little extra "help". Also, the programmer
504 may desire to modify the process described above for his own reasons.
505 For example, it might be desired to suppress the tracking of objects
506 as it is known a priori that the application in question can never
507 create duplicate objects. Serialization of pointers can be "fine tuned"
508 via the specification of <a target="detail" href="traits.html#Traits">Class Serialization Traits</a>
509 as described in
510 <a target="detail" href="special.html#derivedpointers">
511 another section of this manual
512 </a>
513
514 <h3><a name="constructors">Non-Default Constructors</a></h3>
515 Serialization of pointers is implemented in the library with code
516 similar to the following:
517 <pre><code>
518 // load data required for construction and invoke constructor in place
519 template&lt;class Archive, class T&gt;
520 inline void load_construct_data(
521 Archive &amp; ar, T * t, const unsigned int file_version
522 ){
523 // default just uses the default constructor to initialize
524 // previously allocated memory.
525 ::new(t)T();
526 }
527 </code></pre>
528 The default <code style="white-space: normal">load_construct_data</code> invokes the
529 default constructor "in-place" to initialize the memory.
530 <p>
531 If there is no such default constructor, the function templates
532 <code style="white-space: normal">load_construct_data</code> and
533 perhaps <code style="white-space: normal">save_construct_data</code>
534 will have to be overridden. Here is a simple example:
535 <pre><code>
536 class my_class {
537 private:
538 friend class boost::serialization::access;
539 const int m_attribute; // some immutable aspect of the instance
540 int m_state; // mutable state of this instance
541 template&lt;class Archive&gt;
542 void serialize(Archive &amp;ar, const unsigned int file_version){
543 ar &amp; m_state;
544 }
545 public:
546 // no default construct guarentees that no invalid object
547 // ever exists
548 my_class(int attribute) :
549 m_attribute(attribute),
550 m_state(0)
551 {}
552 };
553 </code></pre>
554 the overrides would be:
555 <pre><code>
556 namespace boost { namespace serialization {
557 template&lt;class Archive&gt;
558 inline void save_construct_data(
559 Archive &amp; ar, const my_class * t, const unsigned int file_version
560 ){
561 // save data required to construct instance
562 ar &lt;&lt; t-&gt;m_attribute;
563 }
564
565 template&lt;class Archive&gt;
566 inline void load_construct_data(
567 Archive &amp; ar, my_class * t, const unsigned int file_version
568 ){
569 // retrieve data from archive required to construct new instance
570 int attribute;
571 ar &gt;&gt; attribute;
572 // invoke inplace constructor to initialize instance of my_class
573 ::new(t)my_class(attribute);
574 }
575 }} // namespace ...
576 </code></pre>
577 In addition to the deserialization of pointers, these overrides are used
578 in the deserialization of STL containers whose element type has no default
579 constructor.
580
581 <h3><a name="derivedpointers">Pointers to Objects of Derived Classes</a></h3>
582 <h4><a name="registration">Registration</a></h4>
583 Consider the following:
584 <pre><code>
585 class base {
586 ...
587 };
588 class derived_one : public base {
589 ...
590 };
591 class derived_two : public base {
592 ...
593 };
594 main(){
595 ...
596 base *b;
597 ...
598 ar &amp; b;
599 }
600 </code></pre>
601 When saving <code style="white-space: normal">b</code> what kind of object should be saved?
602 When loading <code style="white-space: normal">b</code> what kind of object should be created?
603 Should it be an object of class <code style="white-space: normal">derived_one</code>,
604 <code style="white-space: normal">derived_two</code>, or maybe <code style="white-space: normal">base</code>?
605 <p>
606 It turns out that the kind of object serialized depends upon whether the base class
607 (<code style="white-space: normal">base</code> in this case) is polymophic or not.
608 If <code style="white-space: normal">base</code> is not polymorphic, that is if it has no
609 virtual functions, then an object of the type <code style="white-space: normal">base</code>
610 will be serialized. Information in any derived classes will be lost. If this is what is desired
611 (it usually isn't) then no other effort is required.
612 <p>
613
614 If the base class is polymorphic, an object of the most derived type
615 (<code style="white-space: normal">derived_one</code>
616 or <code style="white-space: normal">derived_two</code>
617 in this case) will be serialized. The question of which type of object is to be
618 serialized is (almost) automatically handled by the library.
619 <p>
620 The system "registers" each class in an archive the first time an object of that
621 class it is serialized and assigns a sequential number to it. Next time an
622 object of that class is serialized in that same archive, this number is written
623 in the archive. So every class is identified uniquely within the archive.
624 When the archive is read back in, each new sequence number is re-associated with
625 the class being read. Note that this implies that "registration" has to occur
626 during both save and load so that the class-integer table built on load
627 is identical to the class-integer table built on save. In fact, the key to
628 whole serialization system is that things are always saved and loaded in
629 the same sequence. This includes "registration".
630 <p>
631 Expanding our previous example:
632 <pre><code>
633 main(){
634 derived_one d1;
635 derived_two d2:
636 ...
637 ar &amp; d1;
638 ar &amp; d2;
639 // A side effect of serialization of objects d1 and d2 is that
640 // the classes derived_one and derived_two become known to the archive.
641 // So subsequent serialization of those classes by base pointer works
642 // without any special considerations.
643 base *b;
644 ...
645 ar &amp; b;
646 }
647 </code></pre>
648 When <code style="white-space: normal">b</code> is read it is
649 preceded by a unique (to the archive) class identifier which
650 has previously been related to class <code style="white-space: normal">derived_one</code> or
651 <code style="white-space: normal">derived_two</code>.
652 <p>
653 If a derived class has NOT been automatically "registered" as described
654 above, an <a target="detail" href="exceptions.html#unregistered_class">
655 <code style="white-space: normal">unregistered_class</code></a> exception
656 will be thrown when serialization is invoked.
657 <p>
658 This can be addressed by registering the derived class explicitly. All archives are
659 derived from a base class which implements the following template:
660 <pre><code>
661 template&lt;class T&gt;
662 register_type();
663 </code></pre>
664 So our problem could just as well be addressed by writing:
665 <pre><code>
666 main(){
667 ...
668 ar.template register_type&lt;derived_one&gt;();
669 ar.template register_type&lt;derived_two&gt;();
670 base *b;
671 ...
672 ar &amp; b;
673 }
674 </code></pre>
675 Note that if the serialization function is split between save and load, both
676 functions must include the registration. This is required to keep the save
677 and corresponding load in syncronization.
678
679 <h4><a name="export">Export</a></h4>
680 The above will work but may be inconvenient. We don't always know which derived
681 classes we are going to serialize when we write the code to serialize through
682 a base class pointer. Every time a new derived class is written we have to
683 go back to all the places where the base class is serialized and update the
684 code.
685 <p>
686 So we have another method:
687 <pre><code>
688 #include &lt;boost/serialization/export.hpp&gt;
689 ...
690 BOOST_CLASS_EXPORT_GUID(derived_one, "derived_one")
691 BOOST_CLASS_EXPORT_GUID(derived_two, "derived_two")
692
693 main(){
694 ...
695 base *b;
696 ...
697 ar &amp; b;
698 }
699 </code></pre>
700 The macro <code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code> associates a string literal
701 with a class. In the above example we've used a string rendering
702 of the class name. If a object of such an "exported" class is serialized
703 through a pointer and is otherwise unregistered, the "export" string is
704 included in the archive. When the archive
705 is later read, the string literal is used to find the class which
706 should be created by the serialization library.
707 This permits each class to be in a separate header file along with its
708 string identifier. There is no need to maintain a separate "pre-registration"
709 of derived classes that might be serialized. This method of
710 registration is referred to as "key export". More information on this
711 topic is found in the section Class Traits -
712 <a target="detail" href="traits.html#export">Export Key</a>.
713 <p>
714 <h4><a name="instantiation">Instantiation</a></h4>
715 Registration by means of any of the above methods fulfill another role
716 whose importance might not be obvious. This system relies on templated
717 functions of the form <code style="white-space: normal">template&lt;class Archive, class T&gt;</code>.
718 This means that serialization code must be instantiated for each
719 combination of archive and data type that is serialized in the program.
720 <p>
721 Polymorphic pointers of derived classes may never be referred to
722 explictly by the program so normally code to serialize such classes
723 would never be instantiated. So in addition to including export key
724 strings in an archive, <code style="white-space: normal">BOOST_CLASS_EXPORT_GUID</code> explicitly
725 instantiates the class serialization code for all archive classes used
726 by the program.
727
728 <h4><a name="selectivetracking">Selective Tracking</a></h4>
729 Whether or not an object is tracked is determined by its
730 <a target="detail" href="traits.html#tracking">object tracking trait</a>.
731 The default setting for user defined types is <code style="white-space: normal">track_selectively</code>.
732 That is, track objects if and only if they are serialized through pointers anywhere
733 in the program. Any objects that are "registered" by any of the above means are presumed
734 to be serialized through pointers somewhere in the program and therefore
735 would be tracked. In certain situations this could lead to an inefficiency.
736 Suppose we have a class module used by multiple programs. Because
737 some programs serializes polymorphic pointers to objects of this class, we
738 <a target="detail" href="traits.html#export">export</a> a class
739 identifier by specifying <code style="white-space: normal">BOOST_CLASS_EXPORT</code> in the
740 class header. When this module is included by another program,
741 objects of this class will always be tracked even though it
742 may not be necessary. This situation could be addressed by using
743 <a target="detail" href="traits.html#tracking"><code style="white-space: normal">track_never</code></a>
744 in those programs.
745 <p>
746 It could also occur that even though a program serializes through
747 a pointer, we are more concerned with efficiency than avoiding the
748 the possibility of creating duplicate objects. It could be
749 that we happen to know that there will be no duplicates. It could
750 also be that the creation of a few duplicates is benign and not
751 worth avoiding given the runtime cost of tracking duplicates.
752 Again, <a target="detail" href="traits.html#tracking"><code style="white-space: normal">track_never</code></a>
753 can be used.
754 <h4><a name="runtimecasting">Runtime Casting</a></h4>
755 In order to properly translate between base and derived pointers
756 at runtime, the system requires each base/derived pair be found
757 in a table. A side effect of serializing a base object with
758 <code style="white-space: normal">boost::serialization::base_object&lt;Base&gt;(Derived &)</code>
759 is to ensure that the base/derived pair is added to the table
760 before the <code style="white-space: normal">main</code> function is entered.
761 This is very convenient and results in a clean syntax. The only
762 problem is that it can occur where a derived class serialized
763 through a pointer has no need to invoke the serialization of
764 its base class. In such a case, there are two choices. The obvious
765 one is to invoke the base class serialization with <code style="white-space: normal">base_object</code>
766 and specify an empty function for the base class serialization.
767 The alternative is to "register" the Base/Derived relationship
768 explicitly by invoking the template
769 <code style="white-space: normal">void_cast_register&lt;Derived, Base&gt;();</code>.
770 Note that this usage of the term "register" is not related
771 to its usage in the previous section. Here is an example of how this is done:
772 <pre><code>
773 #include &lt;sstream&gt;
774 #include &lt;boost/serialization/serialization.hpp&gt;
775 #include &lt;boost/archive/text_iarchive.hpp&gt;
776 #include &lt;boost/serialization/export.hpp&gt;
777
778 class base {
779 friend class boost::serialization::access;
780 //...
781 // only required when using method 1 below
782 // no real serialization required - specify a vestigial one
783 template&lt;class Archive&gt;
784 void serialize(Archive &amp; ar, const unsigned int file_version){}
785 };
786
787 class derived : public base {
788 friend class boost::serialization::access;
789 template&lt;class Archive&gt;
790 void serialize(Archive &amp; ar, const unsigned int file_version){
791 // method 1 : invoke base class serialization
792 ar & boost::serialization::base_object&lt;base&gt;(*this);
793 // method 2 : explicitly register base/derived relationship
794 boost::serialization::void_cast_register&lt;derived, base&gt;(
795 static_cast&lt;derived *&gt;(NULL),
796 static_cast&lt;base *&gt;(NULL)
797 )
798 }
799 };
800
801 BOOST_CLASS_EXPORT_GUID(derived, "derived")
802
803 main(){
804 //...
805 std::stringstream ss;
806 boost::archive::text_iarchive ar(ss);
807 base *b;
808 ar &gt;&gt; b;
809 }
810 </code></pre>
811 <p>
812
813 In order for this template to be invoked in code compiled by non-conforming
814 compilers, the following syntax may be used:
815 <pre><code>
816 boost::serialization::void_cast_register(
817 static_cast&lt;Derived *&gt;(NULL),
818 static_cast&lt;Base *&gt;(NULL)
819 );
820 </code></pre>
821 For more information, see <a target="detail" href="implementation.html#tempatesyntax">Template Invocation syntax</a>
822
823 <h3><a name="references"></a>References</h3>
824 Classes that contain reference members will generally require
825 non-default constructors as references can only be set when
826 an instance is constructed. The example of the previous section
827 is slightly more complex if the class has reference members.
828 This raises the question of how and where the objects being
829 referred to are stored and how are they created. Also there is the question about
830 references to polymorphic base classes. Basically, these
831 are the same questions that arise regarding pointers. This is
832 no surprise as references are really a special kind of pointer.
833 We address these questions by serializing references as though
834 they were pointers.
835 <pre><code>
836 class object;
837 class my_class {
838 private:
839 friend class boost::serialization::access;
840 int member1;
841 object &amp; member2;
842 template&lt;class Archive&gt;
843 void serialize(Archive &amp;ar, const unsigned int file_version);
844 public:
845 my_class(int m, object &amp; o) :
846 member1(m),
847 member2(o)
848 {}
849 };
850 </code></pre>
851 the overrides would be:
852 <pre><code>
853 namespace boost { namespace serialization {
854 template&lt;class Archive&gt;
855 inline void save_construct_data(
856 Archive &amp; ar, const my_class * t, const unsigned int file_version
857 ){
858 // save data required to construct instance
859 ar &lt;&lt; t.member1;
860 // serialize reference to object as a pointer
861 ar &lt;&lt; &amp; t.member2;
862 }
863
864 template&lt;class Archive&gt;
865 inline void load_construct_data(
866 Archive &amp; ar, my_class * t, const unsigned int file_version
867 ){
868 // retrieve data from archive required to construct new instance
869 int m;
870 ar &gt;&gt; m;
871 // create and load data through pointer to object
872 // tracking handles issues of duplicates.
873 object * optr;
874 ar &gt;&gt; optr;
875 // invoke inplace constructor to initialize instance of my_class
876 ::new(t)my_class(m, *optr);
877 }
878 }} // namespace ...
879 </code></pre>
880
881 <h3><a name="arrays"></a>Arrays</h3>
882 If <code style="white-space: normal">T</code> is a serializable type,
883 then any native C++ array of type T is a serializable type.
884 That is, if <code style="white-space: normal">T</code>
885 is a serializable type, then the following
886 is automatically available and will function as expected:
887 <pre><code>
888 T t[4];
889 ar &lt;&lt; t;
890 ...
891 ar &gt;&gt; t;
892 </code></pre>
893
894 <h2><a href="traits.html">Class Serialization Traits</a></h2>
895
896 <h2><a href="wrappers.html">Serialization Wrappers</a></h2>
897
898 <h2><a name="models"></a>Models - Serialization Implementations Included in the Library</h2>
899 The facilities described above are sufficient to implement
900 serialization for all STL containers. In fact, this has been done
901 and has been included in the library. For example, in order to use
902 the included serialization code for <code style="white-space: normal">std::list</code>, use:
903 <pre><code>
904 #include &lt;boost/serialization/list.hpp&gt;
905 </code></pre>
906 rather than
907 <pre><code>
908 #include &lt;list&gt;
909 </code></pre>
910 Since the former includes the latter, this is all that is necessary.
911 The same holds true for all STL collections as well as templates
912 required to support them (e.g. <code style="white-space: normal">std::pair</code>).
913 <p>
914 As of this writing, the library contains serialization of the following boost classes:
915 <ul>
916 <li>optional
917 <li>variant
918 <li>scoped_ptr
919 <li>shared_ptr
920 <li>auto_ptr (demo)
921 </ul>
922 Others are being added to the list so check the boost files section and headers for
923 new implementations!
924 <hr>
925 <p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
926 Distributed under the Boost Software License, Version 1.0. (See
927 accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
928 </i></p>
929 </body>
930 </html>