Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/serialization/doc/pimpl.html @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 4.6 KB
Line 
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 .
5Use, modification and distribution is subject to the Boost Software
6License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7http://www.boost.org/LICENSE_1_0.txt)
8-->
9<head>
10<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
11<link rel="stylesheet" type="text/css" href="../../../boost.css">
12<link rel="stylesheet" type="text/css" href="style.css">
13<title>Serialization - PIMPL</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">PIMPL</h2>
24    </td>
25  </tr>
26</table>
27<hr>
28PIMPL is a C++ programming idiom described by Herb Sutter <a href="bibliography.html#10">[10]</a>
29which stands for "Private Implementation".  It is also referred to as
30the "Handle Body Idiom". Included in this library is a program called
31<a href="../example/demo_pimpl.cpp" target="demo_impl_cpp">demo_pimpl.cpp</a> 
32which illustrates how this is used. The file
33<a href="../example/demo_pimpl_A.cpp" target="demo_impl__Acpp">demo_pimpl_A.hpp</a>
34contains the declaration of the a class that hides its implementation
35by including a pointer to struct B that is only defined as a pointer.
36<pre><code>
37// class whose declaration is hidden by a pointer
38struct B;
39
40struct A {
41    // class a contains a pointer to a "hidden" declaration
42    B *pimpl;
43    template&lt;class Archive&gt;
44    void serialize(Archive & ar, const unsigned int file_version);
45    A();
46};
47</code></pre>
48Serialization of A requires access to the definition of B in order so it
49is defined in the separately compiled module:
50<a href="../example/demo_pimpl_A.cpp" target="demo_impl_A_cpp">demo_pimpl_A.cpp</a>
51by:
52<pre><code>
53#include "demo_pimpl_A.hpp"
54
55// "hidden" definition of class B
56struct B {
57    int b;
58    template&lt;class Archive&gt;
59    void serialize(Archive & ar, const unsigned int file_version){
60        ar & b;
61    }
62};
63
64A::A() :
65    pimpl(new B)
66{}
67
68A::~A(){
69    delete pimpl;
70}
71
72// now we can define the serialization for class A
73template&lt;class Archive&gt;
74void A::serialize(Archive & ar, const unsigned int file_version){
75    ar & pimpl;
76}
77</code></pre>
78As described in <a href="bibliography.html#10">[10]</a> this brings the
79following advantages:
80<ul>
81    <li>type "B" can be used without using its header.
82    <li>implementation of B can be changed without generating a
83    cascade of recompilations.
84</ul>
85So, we compile the modules and everything is fine.  However when we
86link, we get an error.  Two symbols are undefined:
87<pre><code>
88void A::serialize(boost::archive::text_oarchive & ar, const unsigned int file_version);
89void A::serialize(boost::archive::text_iarchive & ar, const unsigned int file_version);
90</code></pre>
91The problem is that when compiling the above code,
92there is no instantiation of the <code style="white-space: normal">serialize</code> template.
93There can't be as its not "known" what types of archives
94the serialization is going to be used with.  So these functions are "missing"
95when an attempt to link is made.  The solution is to explicitly instantiate
96serialization code for those archives which are going to be used.  In this
97example, including the the following code in any *.cpp file does just that:
98<pre></code>
99#include &lt;boost/archive/text_iarchive.hpp&gt;
100#include &lt;boost/archive/text_oarchive.hpp&gt;
101
102template void A::serialize&lt;boost::archive::text_iarchive&gt;(
103    boost::archive::text_iarchive & ar,
104    const unsigned int file_version
105);
106template void A::serialize&lt;boost::archive::text_oarchive&gt;(
107    boost::archive::text_oarchive & ar,
108    const unsigned int file_version
109);
110</code></pre>
111The program should now link as well as compile.
112<p>
113The downside of this is that one has to know which archives are going
114to be used with hidden serializations.  This is an effect of using template
115driven code.  One can invoke explicity instantiation for all known templates and
116presume that the linker will exclude unreferenced code.  This should
117work but is platform dependent.
118<hr>
119<p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2002-2004.
120Distributed under the Boost Software License, Version 1.0. (See
121accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
122</i></p>
123</body>
124</html>
Note: See TracBrowser for help on using the repository browser.