Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/ptr_container/doc/examples.html @ 47

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

updated boost from 1_33_1 to 1_34_1

File size: 44.7 KB
Line 
1<?xml version="1.0" encoding="utf-8" ?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4<head>
5<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6<meta name="generator" content="Docutils 0.3.10: http://docutils.sourceforge.net/" />
7<title>Boost Pointer Container Library</title>
8<style type="text/css">
9
10/*
11:Author: David Goodger
12:Contact: goodger@users.sourceforge.net
13:Date: $Date: 2006/11/22 22:01:00 $
14:Revision: $Revision: 1.4.2.4 $
15:Copyright: This stylesheet has been placed in the public domain.
16
17Default cascading style sheet for the HTML output of Docutils.
18
19See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
20customize this style sheet.
21*/
22
23/* "! important" is used here to override other ``margin-top`` and
24   ``margin-bottom`` styles that are later in the stylesheet or
25   more specific.  See http://www.w3.org/TR/CSS1#the-cascade */
26.first {
27  margin-top: 0 ! important }
28
29.last, .with-subtitle {
30  margin-bottom: 0 ! important }
31
32.hidden {
33  display: none }
34
35a.toc-backref {
36  text-decoration: none ;
37  color: black }
38
39blockquote.epigraph {
40  margin: 2em 5em ; }
41
42dl.docutils dd {
43  margin-bottom: 0.5em }
44
45/* Uncomment (and remove this text!) to get bold-faced definition list terms
46dl.docutils dt {
47  font-weight: bold }
48*/
49
50div.abstract {
51  margin: 2em 5em }
52
53div.abstract p.topic-title {
54  font-weight: bold ;
55  text-align: center }
56
57div.admonition, div.attention, div.caution, div.danger, div.error,
58div.hint, div.important, div.note, div.tip, div.warning {
59  margin: 2em ;
60  border: medium outset ;
61  padding: 1em }
62
63div.admonition p.admonition-title, div.hint p.admonition-title,
64div.important p.admonition-title, div.note p.admonition-title,
65div.tip p.admonition-title {
66  font-weight: bold ;
67  font-family: sans-serif }
68
69div.attention p.admonition-title, div.caution p.admonition-title,
70div.danger p.admonition-title, div.error p.admonition-title,
71div.warning p.admonition-title {
72  color: red ;
73  font-weight: bold ;
74  font-family: sans-serif }
75
76/* Uncomment (and remove this text!) to get reduced vertical space in
77   compound paragraphs.
78div.compound .compound-first, div.compound .compound-middle {
79  margin-bottom: 0.5em }
80
81div.compound .compound-last, div.compound .compound-middle {
82  margin-top: 0.5em }
83*/
84
85div.dedication {
86  margin: 2em 5em ;
87  text-align: center ;
88  font-style: italic }
89
90div.dedication p.topic-title {
91  font-weight: bold ;
92  font-style: normal }
93
94div.figure {
95  margin-left: 2em }
96
97div.footer, div.header {
98  clear: both;
99  font-size: smaller }
100
101div.line-block {
102  display: block ;
103  margin-top: 1em ;
104  margin-bottom: 1em }
105
106div.line-block div.line-block {
107  margin-top: 0 ;
108  margin-bottom: 0 ;
109  margin-left: 1.5em }
110
111div.sidebar {
112  margin-left: 1em ;
113  border: medium outset ;
114  padding: 1em ;
115  background-color: #ffffee ;
116  width: 40% ;
117  float: right ;
118  clear: right }
119
120div.sidebar p.rubric {
121  font-family: sans-serif ;
122  font-size: medium }
123
124div.system-messages {
125  margin: 5em }
126
127div.system-messages h1 {
128  color: red }
129
130div.system-message {
131  border: medium outset ;
132  padding: 1em }
133
134div.system-message p.system-message-title {
135  color: red ;
136  font-weight: bold }
137
138div.topic {
139  margin: 2em }
140
141h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
142h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
143  margin-top: 0.4em }
144
145h1.title {
146  text-align: center }
147
148h2.subtitle {
149  text-align: center }
150
151hr.docutils {
152  width: 75% }
153
154img.align-left {
155  clear: left }
156
157img.align-right {
158  clear: right }
159
160img.borderless {
161  border: 0 }
162
163ol.simple, ul.simple {
164  margin-bottom: 1em }
165
166ol.arabic {
167  list-style: decimal }
168
169ol.loweralpha {
170  list-style: lower-alpha }
171
172ol.upperalpha {
173  list-style: upper-alpha }
174
175ol.lowerroman {
176  list-style: lower-roman }
177
178ol.upperroman {
179  list-style: upper-roman }
180
181p.attribution {
182  text-align: right ;
183  margin-left: 50% }
184
185p.caption {
186  font-style: italic }
187
188p.credits {
189  font-style: italic ;
190  font-size: smaller }
191
192p.label {
193  white-space: nowrap }
194
195p.rubric {
196  font-weight: bold ;
197  font-size: larger ;
198  color: maroon ;
199  text-align: center }
200
201p.sidebar-title {
202  font-family: sans-serif ;
203  font-weight: bold ;
204  font-size: larger }
205
206p.sidebar-subtitle {
207  font-family: sans-serif ;
208  font-weight: bold }
209
210p.topic-title {
211  font-weight: bold }
212
213pre.address {
214  margin-bottom: 0 ;
215  margin-top: 0 ;
216  font-family: serif ;
217  font-size: 100% }
218
219pre.line-block {
220  font-family: serif ;
221  font-size: 100% }
222
223pre.literal-block, pre.doctest-block {
224  margin-left: 2em ;
225  margin-right: 2em ;
226  background-color: #eeeeee }
227
228span.classifier {
229  font-family: sans-serif ;
230  font-style: oblique }
231
232span.classifier-delimiter {
233  font-family: sans-serif ;
234  font-weight: bold }
235
236span.interpreted {
237  font-family: sans-serif }
238
239span.option {
240  white-space: nowrap }
241
242span.pre {
243  white-space: pre }
244
245span.problematic {
246  color: red }
247
248span.section-subtitle {
249  /* font-size relative to parent (h1..h6 element) */
250  font-size: 80% }
251
252table.citation {
253  border-left: solid thin gray }
254
255table.docinfo {
256  margin: 2em 4em }
257
258table.docutils {
259  margin-top: 0.5em ;
260  margin-bottom: 0.5em }
261
262table.footnote {
263  border-left: solid thin black }
264
265table.docutils td, table.docutils th,
266table.docinfo td, table.docinfo th {
267  padding-left: 0.5em ;
268  padding-right: 0.5em ;
269  vertical-align: top }
270
271table.docutils th.field-name, table.docinfo th.docinfo-name {
272  font-weight: bold ;
273  text-align: left ;
274  white-space: nowrap ;
275  padding-left: 0 }
276
277h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
278h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
279  font-size: 100% }
280
281tt.docutils {
282  background-color: #eeeeee }
283
284ul.auto-toc {
285  list-style-type: none }
286
287</style>
288</head>
289<body>
290<div class="document" id="boost-pointer-container-library">
291<h1 class="title"><img alt="Boost" src="boost.png" /> Pointer Container Library</h1>
292<h2 class="subtitle" id="examples">Examples</h2>
293<p>Some examples are given here and in the accompanying test files:</p>
294<div class="contents local topic">
295<ul class="simple">
296<li><a class="reference" href="#null-pointers-cannot-be-stored-in-the-containers" id="id2" name="id2">1. Null pointers cannot be stored in the containers</a></li>
297<li><a class="reference" href="#iterators-and-other-operations-return-indirected-values" id="id3" name="id3">2. Iterators and other operations return indirected values</a></li>
298<li><a class="reference" href="#copy-semantics-of-pointer-containers" id="id4" name="id4">3. Copy-semantics of pointer containers</a></li>
299<li><a class="reference" href="#making-a-non-copyable-type-clonable" id="id5" name="id5">4. Making a non-copyable type Clonable</a></li>
300<li><a class="reference" href="#objects-are-cloned-before-insertion-inserted-pointers-are-owned-by-the-container" id="id6" name="id6">5. Objects are cloned before insertion, inserted pointers are owned by the container</a></li>
301<li><a class="reference" href="#transferring-ownership-of-a-single-element" id="id7" name="id7">6. Transferring ownership of a single element</a></li>
302<li><a class="reference" href="#transferring-ownership-of-pointers-between-different-pointer-containers" id="id8" name="id8">7. Transferring ownership of pointers between different pointer containers</a></li>
303<li><a class="reference" href="#selected-test-files" id="id9" name="id9">8. Selected test files</a></li>
304<li><a class="reference" href="#a-large-example" id="id10" name="id10">9. A large example</a></li>
305</ul>
306</div>
307<div class="section">
308<h1><a class="toc-backref" href="#id2" id="null-pointers-cannot-be-stored-in-the-containers" name="null-pointers-cannot-be-stored-in-the-containers"><span id="example-1"></span>1. Null pointers cannot be stored in the containers</a></h1>
309<pre class="literal-block">
310my_container.push_back( 0 );            // throws bad_ptr
311my_container.replace( an_iterator, 0 ); // throws bad_ptr
312my_container.insert( an_iterator, 0 );  // throws bad_ptr       
313std::auto_ptr&lt;T&gt; p( 0 );
314my_container.push_back( p );            // throws bad_ptr                                                         
315</pre>
316</div>
317<div class="section">
318<h1><a class="toc-backref" href="#id3" id="iterators-and-other-operations-return-indirected-values" name="iterators-and-other-operations-return-indirected-values"><span id="example-2"></span>2. Iterators and other operations return indirected values</a></h1>
319<pre class="literal-block">
320ptr_vector&lt;X&gt; pvec;
321std::vector&lt;X*&gt; vec;
322*vec.begin()  = new X;   // fine, memory leak
323*pvec.begin() = new X;   // compile time error
324( *vec.begin() )-&gt;foo(); // call X::foo(), a bit clumsy
325pvec.begin()-&gt;foo();     // no indirection needed
326*vec.front()  = X();     // overwrite first element
327pvec.front()  = X();     // no indirection needed
328</pre>
329</div>
330<div class="section">
331<h1><a class="toc-backref" href="#id4" id="copy-semantics-of-pointer-containers" name="copy-semantics-of-pointer-containers"><span id="example-3"></span>3. Copy-semantics of pointer containers</a></h1>
332<pre class="literal-block">
333ptr_vector&lt;T&gt; vec1;
334...
335ptr_vector&lt;T&gt; vec2( vec1.clone() ); // deep copy objects of 'vec1' and use them to construct 'vec2', could be very expensive
336vec2 = vec1.release();              // give up ownership of pointers in 'vec1' and pass the ownership to 'vec2', rather cheap
337vec2.release();                     // give up ownership; the objects will be deallocated if not assigned to another container
338vec1 = vec2;                        // compile time error: 'operator=()' not defined
339ptr_vector&lt;T&gt; vec3( vec1 );         // compile time error: copy-constructor not defined
340</pre>
341</div>
342<div class="section">
343<h1><a class="toc-backref" href="#id5" id="making-a-non-copyable-type-clonable" name="making-a-non-copyable-type-clonable"><span id="example-4"></span>4. Making a non-copyable type Clonable</a></h1>
344<pre class="literal-block">
345 // a class that has no normal copy semantics
346class X : boost::noncopyable { public: X* clone() const; ... };
347                                                                   
348// this will be found by the library by argument dependent lookup (ADL)                                                                 
349X* new_clone( const X&amp; x )
350{ return x.clone(); }
351                                                                   
352// we can now use the interface that requires clonability
353ptr_vector&lt;X&gt; vec1, vec2;
354...
355vec2 = vec1.clone();                                 // 'clone()' requires cloning &lt;g&gt; 
356vec2.insert( vec2.end(), vec1.begin(), vec1.end() ); // inserting always means inserting clones
357</pre>
358</div>
359<div class="section">
360<h1><a class="toc-backref" href="#id6" id="objects-are-cloned-before-insertion-inserted-pointers-are-owned-by-the-container" name="objects-are-cloned-before-insertion-inserted-pointers-are-owned-by-the-container"><span id="example-5"></span>5. Objects are cloned before insertion, inserted pointers are owned by the container</a></h1>
361<pre class="literal-block">
362class X { ... };                     // assume 'X' is Clonable
363X x;                                 // and 'X' can be stack-allocated
364ptr_list&lt;X&gt; list;
365list.push_back( new_clone( x ) );    // insert a clone
366list.push_back( new X );             // always give the pointer directly to the container to avoid leaks
367list.push_back( &amp;x );                // don't do this!!!
368std::auto_ptr&lt;X&gt; p( new X );
369list.push_back( p );                 // give up ownership
370BOOST_ASSERT( p.get() == 0 );
371</pre>
372</div>
373<div class="section">
374<h1><a class="toc-backref" href="#id7" id="transferring-ownership-of-a-single-element" name="transferring-ownership-of-a-single-element"><span id="example-6"></span>6. Transferring ownership of a single element</a></h1>
375<pre class="literal-block">
376ptr_deque&lt;T&gt;                    deq;
377typedef ptr_deque&lt;T&gt;::auto_type auto_type;
378
379// ... fill the container somehow
380
381auto_type ptr  = deq.release_back();             // remove back element from container and give up ownership
382auto_type ptr2 = deq.release( deq.begin() + 2 ); // use an iterator to determine the element to release
383ptr            = deq.release_front();            // supported for 'ptr_list' and 'ptr_deque'
384                               
385deq.push_back( ptr.release() );                  // give ownership back to the container
386</pre>
387</div>
388<div class="section">
389<h1><a class="toc-backref" href="#id8" id="transferring-ownership-of-pointers-between-different-pointer-containers" name="transferring-ownership-of-pointers-between-different-pointer-containers"><span id="example-7"></span>7. Transferring ownership of pointers between different pointer containers</a></h1>
390<pre class="literal-block">
391ptr_list&lt;X&gt; list; ptr_vector&lt;X&gt; vec;
392...
393//
394// note: no cloning happens in these examples                               
395//
396list.transfer( list.begin(), vec.begin(), vec );           // make the first element of 'vec' the first element of 'list'
397vec.transfer( vec.end(), list.begin(), list.end(), list ); // put all the lists element into the vector                                 
398</pre>
399<p>We can also transfer objects from <tt class="docutils literal"><span class="pre">ptr_container&lt;Derived&gt;</span></tt> to <tt class="docutils literal"><span class="pre">ptr_container&lt;Base</span></tt> without any problems.</p>
400</div>
401<div class="section">
402<h1><a class="toc-backref" href="#id9" id="selected-test-files" name="selected-test-files"><span id="example-8"></span>8. Selected test files</a></h1>
403<table class="docutils field-list" frame="void" rules="none">
404<col class="field-name" />
405<col class="field-body" />
406<tbody valign="top">
407<tr class="field"><th class="field-name" colspan="2"><a class="reference" href="../test/incomplete_type_test.cpp">incomplete_type_test.cpp</a>:</th></tr>
408<tr><td>&nbsp;</td><td class="field-body">Shows how to implement the Composite pattern.</td>
409</tr>
410<tr class="field"><th class="field-name" colspan="2"><a class="reference" href="../test/simple_test.cpp">simple_test.cpp</a>:</th></tr>
411<tr><td>&nbsp;</td><td class="field-body">Shows how the usage of pointer container compares with a
412container of smart pointers</td>
413</tr>
414<tr class="field"><th class="field-name" colspan="2"><a class="reference" href="../test/view_example.cpp">view_example.cpp</a>:</th></tr>
415<tr><td>&nbsp;</td><td class="field-body">Shows how to use a pointer container as a view into other container</td>
416</tr>
417<tr class="field"><th class="field-name"><a class="reference" href="../test/tree_test.cpp">tree_test.cpp</a>:</th><td class="field-body">Shows how to make a tree-structure</td>
418</tr>
419<tr class="field"><th class="field-name"><a class="reference" href="../test/ptr_array.cpp">array_test.cpp</a>:</th><td class="field-body">Shows how to make an n-ary tree</td>
420</tr>
421</tbody>
422</table>
423</div>
424<div class="section">
425<h1><a class="toc-backref" href="#id10" id="a-large-example" name="a-large-example">9. A large example</a></h1>
426<p>This examples shows many of the most common
427features at work. The example provide lots of comments.</p>
428<html>
429<head>
430<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
431<title> </title>
432<link rel="stylesheet" href="style.css" type="text/css">
433</head>
434
435<body>
436    <pre><span class=comment>//
437// Boost.Pointer Container
438//
439//  Copyright Thorsten Ottosen 2003-2005. Use, modification and
440//  distribution is subject to the Boost Software License, Version
441//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
442//  http://www.boost.org/LICENSE_1_0.txt)
443//
444// For more information, see http://www.boost.org/libs/ptr_container/
445//
446
447//
448// This example is intended to get you started.
449// Notice how the smart container
450//
451// 1. takes ownership of objects
452// 2. transfers ownership
453// 3. applies indirection to iterators
454// 4. clones objects from other smart containers
455//
456
457//
458// First we select which container to use.
459//</span>
460<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>ptr_container</span><span class=special>/</span><span class=identifier>ptr_deque</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
461
462<span class=comment>//
463// we need these later in the example
464//</span>
465<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>assert</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
466<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>string</span><span class=special>&gt;</span>
467<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>exception</span><span class=special>&gt;</span>
468
469
470<span class=comment>//
471// Then we define a small polymorphic class
472// hierarchy.
473//</span> 
474
475<span class=keyword>class</span> <span class=identifier>animal</span> <span class=special>:</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>noncopyable</span>
476<span class=special>{</span>
477    <span class=keyword>virtual</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>do_speak</span><span class=special>()</span> <span class=keyword>const</span> <span class=special>=</span> <span class=number>0</span><span class=special>;</span>
478    <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>name_</span><span class=special>;</span>
479
480<span class=keyword>protected</span><span class=special>:</span>
481    <span class=comment>//
482    // Animals cannot be copied...
483    //</span>
484    <span class=identifier>animal</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>animal</span><span class=special>&amp;</span> <span class=identifier>r</span> <span class=special>)</span> <span class=special>:</span> <span class=identifier>name_</span><span class=special>(</span> <span class=identifier>r</span><span class=special>.</span><span class=identifier>name_</span> <span class=special>)</span>           <span class=special>{</span> <span class=special>}</span>
485    <span class=keyword>void</span> <span class=keyword>operator</span><span class=special>=(</span> <span class=keyword>const</span> <span class=identifier>animal</span><span class=special>&amp;</span> <span class=special>);</span>
486
487<span class=keyword>private</span><span class=special>:</span>
488    <span class=comment>//
489    // ...but due to advances in genetics, we can clone them!
490    //</span>
491
492    <span class=keyword>virtual</span> <span class=identifier>animal</span><span class=special>*</span> <span class=identifier>do_clone</span><span class=special>()</span> <span class=keyword>const</span> <span class=special>=</span> <span class=number>0</span><span class=special>;</span>
493       
494<span class=keyword>public</span><span class=special>:</span>
495    <span class=identifier>animal</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&amp;</span> <span class=identifier>name</span> <span class=special>)</span> <span class=special>:</span> <span class=identifier>name_</span><span class=special>(</span><span class=identifier>name</span><span class=special>)</span>        <span class=special>{</span> <span class=special>}</span>
496    <span class=keyword>virtual</span> <span class=special>~</span><span class=identifier>animal</span><span class=special>()</span> <span class=keyword>throw</span><span class=special>()</span>                              <span class=special>{</span> <span class=special>}</span>
497   
498    <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>speak</span><span class=special>()</span> <span class=keyword>const</span>
499    <span class=special>{</span>
500        <span class=keyword>return</span> <span class=identifier>do_speak</span><span class=special>();</span>
501    <span class=special>}</span>
502
503    <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>name</span><span class=special>()</span> <span class=keyword>const</span>
504    <span class=special>{</span>
505        <span class=keyword>return</span> <span class=identifier>name_</span><span class=special>;</span>
506    <span class=special>}</span>
507
508    <span class=identifier>animal</span><span class=special>*</span> <span class=identifier>clone</span><span class=special>()</span> <span class=keyword>const</span>
509    <span class=special>{</span>
510        <span class=keyword>return</span> <span class=identifier>do_clone</span><span class=special>();</span>
511    <span class=special>}</span>
512<span class=special>};</span>
513
514<span class=comment>//
515// An animal is still not Clonable. We need this last hook.
516//
517// Notice that we pass the animal by const reference
518// and return by pointer.
519//</span>
520
521<span class=identifier>animal</span><span class=special>*</span> <span class=identifier>new_clone</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>animal</span><span class=special>&amp;</span> <span class=identifier>a</span> <span class=special>)</span>
522<span class=special>{</span>
523    <span class=keyword>return</span> <span class=identifier>a</span><span class=special>.</span><span class=identifier>clone</span><span class=special>();</span>
524<span class=special>}</span>
525
526<span class=comment>//
527// We do not need to define 'delete_clone()' since
528// since the default is to call the default 'operator delete()'.
529//</span>
530
531<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>muuuh</span> <span class=special>=</span> <span class=string>&quot;Muuuh!&quot;</span><span class=special>;</span>
532<span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>oiink</span> <span class=special>=</span> <span class=string>&quot;Oiiink&quot;</span><span class=special>;</span>
533
534<span class=keyword>class</span> <span class=identifier>cow</span> <span class=special>:</span> <span class=keyword>public</span> <span class=identifier>animal</span>
535<span class=special>{</span>
536    <span class=keyword>virtual</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>do_speak</span><span class=special>()</span> <span class=keyword>const</span>
537    <span class=special>{</span>
538        <span class=keyword>return</span> <span class=identifier>muuuh</span><span class=special>;</span>
539    <span class=special>}</span>
540
541    <span class=keyword>virtual</span> <span class=identifier>animal</span><span class=special>*</span> <span class=identifier>do_clone</span><span class=special>()</span> <span class=keyword>const</span>
542    <span class=special>{</span>
543        <span class=keyword>return</span> <span class=keyword>new</span> <span class=identifier>cow</span><span class=special>(</span> <span class=special>*</span><span class=keyword>this</span> <span class=special>);</span>
544    <span class=special>}</span>
545
546<span class=keyword>public</span><span class=special>:</span>
547    <span class=identifier>cow</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&amp;</span> <span class=identifier>name</span> <span class=special>)</span> <span class=special>:</span> <span class=identifier>animal</span><span class=special>(</span><span class=identifier>name</span><span class=special>)</span>          <span class=special>{</span> <span class=special>}</span>
548<span class=special>};</span>
549
550<span class=keyword>class</span> <span class=identifier>pig</span> <span class=special>:</span> <span class=keyword>public</span> <span class=identifier>animal</span>
551<span class=special>{</span>
552    <span class=keyword>virtual</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>do_speak</span><span class=special>()</span> <span class=keyword>const</span>
553    <span class=special>{</span>
554        <span class=keyword>return</span> <span class=identifier>oiink</span><span class=special>;</span>
555    <span class=special>}</span>
556
557    <span class=keyword>virtual</span> <span class=identifier>animal</span><span class=special>*</span> <span class=identifier>do_clone</span><span class=special>()</span> <span class=keyword>const</span>
558    <span class=special>{</span>
559        <span class=keyword>return</span> <span class=keyword>new</span> <span class=identifier>pig</span><span class=special>(</span> <span class=special>*</span><span class=keyword>this</span> <span class=special>);</span>
560    <span class=special>}</span>
561   
562<span class=keyword>public</span><span class=special>:</span>
563    <span class=identifier>pig</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&amp;</span> <span class=identifier>name</span> <span class=special>)</span> <span class=special>:</span> <span class=identifier>animal</span><span class=special>(</span><span class=identifier>name</span><span class=special>)</span>          <span class=special>{</span> <span class=special>}</span>
564<span class=special>};</span>
565
566<span class=comment>//
567// Then we, of course, need a place to put all
568// those animals.
569//</span>
570
571<span class=keyword>class</span> <span class=identifier>farm</span>
572<span class=special>{</span>
573    <span class=comment>//
574    // This is where the smart containers are handy
575    //</span>
576    <span class=keyword>typedef</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>ptr_deque</span><span class=special>&lt;</span><span class=identifier>animal</span><span class=special>&gt;</span> <span class=identifier>barn_type</span><span class=special>;</span>
577    <span class=identifier>barn_type</span>                        <span class=identifier>barn</span><span class=special>;</span>
578
579    <span class=comment>//
580    // An error type
581    //</span>
582    <span class=keyword>struct</span> <span class=identifier>farm_trouble</span> <span class=special>:</span> <span class=keyword>public</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>exception</span>           <span class=special>{</span> <span class=special>};</span>
583
584<span class=keyword>public</span><span class=special>:</span>
585    <span class=comment>//
586    // We would like to make it possible to
587    // iterate over the animals in the farm
588    //</span>
589    <span class=keyword>typedef</span> <span class=identifier>barn_type</span><span class=special>::</span><span class=identifier>iterator</span>  <span class=identifier>animal_iterator</span><span class=special>;</span>
590
591    <span class=comment>//
592    // We also need to count the farm's size...
593    //</span>
594    <span class=keyword>typedef</span> <span class=identifier>barn_type</span><span class=special>::</span><span class=identifier>size_type</span> <span class=identifier>size_type</span><span class=special>;</span>
595   
596    <span class=comment>//
597    // And we also want to transfer an animal
598    // safely around. The easiest way to think
599    // about '::auto_type' is to imagine a simplified
600    // 'std::auto_ptr&lt;T&gt;' ... this means you can expect
601    //
602    //   T* operator-&gt;()
603    //   T* release()
604    //   deleting destructor
605    //
606    // but not more.
607    //</span>
608    <span class=keyword>typedef</span> <span class=identifier>barn_type</span><span class=special>::</span><span class=identifier>auto_type</span>  <span class=identifier>animal_transport</span><span class=special>;</span>
609
610    <span class=comment>//
611    // Create an empty farm.
612    //</span>
613    <span class=identifier>farm</span><span class=special>()</span>                                                 <span class=special>{</span> <span class=special>}</span>
614   
615    <span class=comment>//
616    // We need a constructor that can make a new
617    // farm by cloning a range of animals.
618    //</span>
619    <span class=identifier>farm</span><span class=special>(</span> <span class=identifier>animal_iterator</span> <span class=identifier>begin</span><span class=special>,</span> <span class=identifier>animal_iterator</span> <span class=identifier>end</span> <span class=special>)</span>
620     <span class=special>:</span> 
621        <span class=comment>//
622        // Objects are always cloned before insertion
623        // unless we explicitly add a pointer or
624        // use 'release()'. Therefore we actually
625        // clone all animals in the range
626        //</span>
627        <span class=identifier>barn</span><span class=special>(</span> <span class=identifier>begin</span><span class=special>,</span> <span class=identifier>end</span> <span class=special>)</span>                               <span class=special>{</span> <span class=special>}</span>
628   
629    <span class=comment>//
630    // ... so we need some other function too
631    //</span>
632
633    <span class=identifier>animal_iterator</span> <span class=identifier>begin</span><span class=special>()</span>
634    <span class=special>{</span>
635        <span class=keyword>return</span> <span class=identifier>barn</span><span class=special>.</span><span class=identifier>begin</span><span class=special>();</span>
636    <span class=special>}</span>
637
638    <span class=identifier>animal_iterator</span> <span class=identifier>end</span><span class=special>()</span>
639    <span class=special>{</span>
640        <span class=keyword>return</span> <span class=identifier>barn</span><span class=special>.</span><span class=identifier>end</span><span class=special>();</span>
641    <span class=special>}</span>
642   
643    <span class=comment>//
644    // Here it is quite ok to have an 'animal*' argument.
645    // The smart container will handle all ownership
646    // issues.
647    //</span>
648    <span class=keyword>void</span> <span class=identifier>buy_animal</span><span class=special>(</span> <span class=identifier>animal</span><span class=special>*</span> <span class=identifier>a</span> <span class=special>)</span>
649    <span class=special>{</span>
650        <span class=identifier>barn</span><span class=special>.</span><span class=identifier>push_back</span><span class=special>(</span> <span class=identifier>a</span> <span class=special>);</span>
651    <span class=special>}</span>
652
653    <span class=comment>//
654    // The farm can also be in economical trouble and
655    // therefore be in the need to sell animals.
656    //</span>
657    <span class=identifier>animal_transport</span> <span class=identifier>sell_animal</span><span class=special>(</span> <span class=identifier>animal_iterator</span> <span class=identifier>to_sell</span> <span class=special>)</span>
658    <span class=special>{</span>
659        <span class=keyword>if</span><span class=special>(</span> <span class=identifier>to_sell</span> <span class=special>==</span> <span class=identifier>end</span><span class=special>()</span> <span class=special>)</span>
660            <span class=keyword>throw</span> <span class=identifier>farm_trouble</span><span class=special>();</span>
661
662        <span class=comment>//
663        // Here we remove the animal from the barn,
664        // but the animal is not deleted yet...it's
665        // up to the buyer to decide what
666        // to do with it.
667        //</span>
668        <span class=keyword>return</span> <span class=identifier>barn</span><span class=special>.</span><span class=identifier>release</span><span class=special>(</span> <span class=identifier>to_sell</span> <span class=special>);</span>
669    <span class=special>}</span>
670
671    <span class=comment>//
672    // How big a farm do we have?
673    //</span>
674    <span class=identifier>size_type</span> <span class=identifier>size</span><span class=special>()</span> <span class=keyword>const</span>
675    <span class=special>{</span>
676        <span class=keyword>return</span> <span class=identifier>barn</span><span class=special>.</span><span class=identifier>size</span><span class=special>();</span>
677    <span class=special>}</span>
678
679    <span class=comment>//
680    // If things are bad, we might choose to sell all animals :-(
681    //</span>
682    <span class=identifier>std</span><span class=special>::</span><span class=identifier>auto_ptr</span><span class=special>&lt;</span><span class=identifier>barn_type</span><span class=special>&gt;</span> <span class=identifier>sell_farm</span><span class=special>()</span>
683    <span class=special>{</span>
684        <span class=keyword>return</span> <span class=identifier>barn</span><span class=special>.</span><span class=identifier>release</span><span class=special>();</span>
685    <span class=special>}</span>
686
687    <span class=comment>//
688    // However, if things are good, we might buy somebody
689    // else's farm :-)
690    //</span>
691
692    <span class=keyword>void</span> <span class=identifier>buy_farm</span><span class=special>(</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>auto_ptr</span><span class=special>&lt;</span><span class=identifier>barn_type</span><span class=special>&gt;</span> <span class=identifier>other</span> <span class=special>)</span>
693    <span class=special>{</span>
694        <span class=comment>//
695        // This line inserts all the animals from 'other'
696        // and is guaranteed either to succeed or to have no
697        // effect
698        //</span>
699        <span class=identifier>barn</span><span class=special>.</span><span class=identifier>transfer</span><span class=special>(</span> <span class=identifier>barn</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span> <span class=comment>// insert new animals at the end</span>
700                         <span class=special>*</span><span class=identifier>other</span> <span class=special>);</span>     <span class=comment>// we want to transfer all animals,
701                                       // so we use the whole container as argument
702        //
703        // You might think you would have to do
704        //
705        // other.release();
706        //
707        // but '*other' is empty and can go out of scope as it wants
708        //</span>
709        <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>other</span><span class=special>-&gt;</span><span class=identifier>empty</span><span class=special>()</span> <span class=special>);</span>
710    <span class=special>}</span>
711   
712<span class=special>};</span> <span class=comment>// class 'farm'.</span>
713
714<span class=keyword>int</span> <span class=identifier>main</span><span class=special>()</span>
715<span class=special>{</span>
716    <span class=comment>//
717    // First we make a farm
718    //</span>
719    <span class=identifier>farm</span> <span class=identifier>animal_farm</span><span class=special>;</span>
720    <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>size</span><span class=special>()</span> <span class=special>==</span> <span class=number>0u</span> <span class=special>);</span>
721   
722    <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>buy_animal</span><span class=special>(</span> <span class=keyword>new</span> <span class=identifier>pig</span><span class=special>(</span><span class=string>&quot;Betty&quot;</span><span class=special>)</span> <span class=special>);</span>
723    <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>buy_animal</span><span class=special>(</span> <span class=keyword>new</span> <span class=identifier>pig</span><span class=special>(</span><span class=string>&quot;Benny&quot;</span><span class=special>)</span> <span class=special>);</span>
724    <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>buy_animal</span><span class=special>(</span> <span class=keyword>new</span> <span class=identifier>pig</span><span class=special>(</span><span class=string>&quot;Jeltzin&quot;</span><span class=special>)</span> <span class=special>);</span>
725    <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>buy_animal</span><span class=special>(</span> <span class=keyword>new</span> <span class=identifier>cow</span><span class=special>(</span><span class=string>&quot;Hanz&quot;</span><span class=special>)</span> <span class=special>);</span>
726    <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>buy_animal</span><span class=special>(</span> <span class=keyword>new</span> <span class=identifier>cow</span><span class=special>(</span><span class=string>&quot;Mary&quot;</span><span class=special>)</span> <span class=special>);</span>
727    <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>buy_animal</span><span class=special>(</span> <span class=keyword>new</span> <span class=identifier>cow</span><span class=special>(</span><span class=string>&quot;Frederik&quot;</span><span class=special>)</span> <span class=special>);</span>
728    <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>size</span><span class=special>()</span> <span class=special>==</span> <span class=number>6u</span> <span class=special>);</span>
729
730    <span class=comment>//
731    // Then we make another farm...it will actually contain
732    // a clone of the other farm.
733    //</span>
734    <span class=identifier>farm</span> <span class=identifier>new_farm</span><span class=special>(</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>end</span><span class=special>()</span> <span class=special>);</span>
735    <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>new_farm</span><span class=special>.</span><span class=identifier>size</span><span class=special>()</span> <span class=special>==</span> <span class=number>6u</span> <span class=special>);</span>
736
737    <span class=comment>//
738    // Is it really clones in the new farm?
739    //</span>
740    <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>new_farm</span><span class=special>.</span><span class=identifier>begin</span><span class=special>()-&gt;</span><span class=identifier>name</span><span class=special>()</span> <span class=special>==</span> <span class=string>&quot;Betty&quot;</span> <span class=special>);</span>
741   
742    <span class=comment>//
743    // Then we search for an animal, Mary (the Crown Princess of Denmark),
744    // because we would like to buy her ...
745    //</span>
746    <span class=keyword>typedef</span> <span class=identifier>farm</span><span class=special>::</span><span class=identifier>animal_iterator</span> <span class=identifier>iterator</span><span class=special>;</span>
747    <span class=identifier>iterator</span> <span class=identifier>to_sell</span><span class=special>;</span>
748    <span class=keyword>for</span><span class=special>(</span> <span class=identifier>iterator</span> <span class=identifier>i</span>   <span class=special>=</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span>
749                  <span class=identifier>end</span> <span class=special>=</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>end</span><span class=special>();</span>
750         <span class=identifier>i</span> <span class=special>!=</span> <span class=identifier>end</span><span class=special>;</span> <span class=special>++</span><span class=identifier>i</span> <span class=special>)</span>
751    <span class=special>{</span>
752        <span class=keyword>if</span><span class=special>(</span> <span class=identifier>i</span><span class=special>-&gt;</span><span class=identifier>name</span><span class=special>()</span> <span class=special>==</span> <span class=string>&quot;Mary&quot;</span> <span class=special>)</span>
753        <span class=special>{</span>
754            <span class=identifier>to_sell</span> <span class=special>=</span> <span class=identifier>i</span><span class=special>;</span>
755            <span class=keyword>break</span><span class=special>;</span>
756        <span class=special>}</span>
757    <span class=special>}</span>
758
759    <span class=identifier>farm</span><span class=special>::</span><span class=identifier>animal_transport</span> <span class=identifier>mary</span> <span class=special>=</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>sell_animal</span><span class=special>(</span> <span class=identifier>to_sell</span> <span class=special>);</span>
760
761
762    <span class=keyword>if</span><span class=special>(</span> <span class=identifier>mary</span><span class=special>-&gt;</span><span class=identifier>speak</span><span class=special>()</span> <span class=special>==</span> <span class=identifier>muuuh</span> <span class=special>)</span>
763        <span class=comment>//
764        // Great, Mary is a cow, and she may live longer
765        //</span>
766        <span class=identifier>new_farm</span><span class=special>.</span><span class=identifier>buy_animal</span><span class=special>(</span> <span class=identifier>mary</span><span class=special>.</span><span class=identifier>release</span><span class=special>()</span> <span class=special>);</span>
767    <span class=keyword>else</span>
768        <span class=comment>//
769        // Then the animal would be destroyed (!)
770        // when we go out of scope.
771        //</span>
772        <span class=special>;</span>
773
774    <span class=comment>//
775    // Now we can observe some changes to the two farms...
776    //</span>
777    <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>size</span><span class=special>()</span> <span class=special>==</span> <span class=number>5u</span> <span class=special>);</span>
778    <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>new_farm</span><span class=special>.</span><span class=identifier>size</span><span class=special>()</span>    <span class=special>==</span> <span class=number>7u</span> <span class=special>);</span>
779
780    <span class=comment>//
781    // The new farm has however underestimated how much
782    // it cost to feed Mary and its owner is forced to sell the farm...
783    //</span>
784    <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>buy_farm</span><span class=special>(</span> <span class=identifier>new_farm</span><span class=special>.</span><span class=identifier>sell_farm</span><span class=special>()</span> <span class=special>);</span>
785
786    <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>new_farm</span><span class=special>.</span><span class=identifier>size</span><span class=special>()</span>    <span class=special>==</span> <span class=number>0u</span> <span class=special>);</span>
787    <span class=identifier>BOOST_ASSERT</span><span class=special>(</span> <span class=identifier>animal_farm</span><span class=special>.</span><span class=identifier>size</span><span class=special>()</span> <span class=special>==</span> <span class=number>12u</span> <span class=special>);</span>     
788<span class=special>}</span>
789</pre>
790</body>
791
792</html>
793<!-- 10. Changing the Clone Allocator
794++++++++++++++++++++++++++++++++
795
796This example shows how we can change
797the Clone Allocator to use the pointer containers
798as view into other containers:
799
800.. raw:: html
801        :file: tut2.html -->
802<hr><p><strong>Navigate:</strong></p>
803<ul class="simple">
804<li><a class="reference" href="ptr_container.html">home</a></li>
805<li><a class="reference" href="reference.html">reference</a></li>
806</ul>
807<hr><table class="docutils field-list" frame="void" rules="none">
808<col class="field-name" />
809<col class="field-body" />
810<tbody valign="top">
811<tr class="field"><th class="field-name">Copyright:</th><td class="field-body">Thorsten Ottosen 2004-2006. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see <a class="reference" href="http://www.boost.org/LICENSE_1_0.txt">LICENSE_1_0.txt</a>).</td>
812</tr>
813</tbody>
814</table>
815</div>
816</div>
817</body>
818</html>
Note: See TracBrowser for help on using the repository browser.