serialization.html 39 KB

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