]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | ++++++++++++++++++++++++++++++++++ |
2 | |Boost| Pointer Container Library | |
3 | ++++++++++++++++++++++++++++++++++ | |
4 | ||
5 | .. |Boost| image:: boost.png | |
6 | ||
7 | ======== | |
8 | Examples | |
9 | ======== | |
10 | ||
11 | Some examples are given here and in the accompanying test files: | |
12 | ||
13 | .. contents:: :local: | |
14 | ||
15 | ||
16 | .. _`Example 1`: | |
17 | ||
18 | 1. Null pointers cannot be stored in the containers | |
19 | +++++++++++++++++++++++++++++++++++++++++++++++++++ | |
20 | ||
21 | :: | |
22 | ||
23 | my_container.push_back( 0 ); // throws bad_ptr | |
24 | my_container.replace( an_iterator, 0 ); // throws bad_ptr | |
25 | my_container.insert( an_iterator, 0 ); // throws bad_ptr | |
26 | std::auto_ptr<T> p( 0 ); | |
27 | my_container.push_back( p ); // throws bad_ptr | |
28 | ||
29 | .. _`Example 2`: | |
30 | ||
31 | 2. Iterators and other operations return indirected values | |
32 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
33 | ||
34 | :: | |
35 | ||
36 | ptr_vector<X> pvec; | |
37 | std::vector<X*> vec; | |
38 | *vec.begin() = new X; // fine, memory leak | |
39 | *pvec.begin() = new X; // compile time error | |
40 | ( *vec.begin() )->foo(); // call X::foo(), a bit clumsy | |
41 | pvec.begin()->foo(); // no indirection needed | |
42 | *vec.front() = X(); // overwrite first element | |
43 | pvec.front() = X(); // no indirection needed | |
44 | ||
45 | ||
46 | .. _`Example 3`: | |
47 | ||
48 | 3. Copy-semantics of pointer containers | |
49 | +++++++++++++++++++++++++++++++++++++++ | |
50 | ||
51 | :: | |
52 | ||
53 | ptr_vector<T> vec1; | |
54 | ... | |
55 | ptr_vector<T> vec2( vec1.clone() ); // deep copy objects of 'vec1' and use them to construct 'vec2', could be very expensive | |
56 | vec2 = vec1.release(); // give up ownership of pointers in 'vec1' and pass the ownership to 'vec2', rather cheap | |
57 | vec2.release(); // give up ownership; the objects will be deallocated if not assigned to another container | |
58 | vec1 = vec2; // deep copy objects of 'vec2' and assign them to 'vec1', could be very expensive | |
59 | ptr_vector<T> vec3( vec1 ); // deep copy objects of 'vec1', could be very expensive | |
60 | ||
61 | ||
62 | .. _`Example 4`: | |
63 | ||
64 | 4. Making a non-copyable type Cloneable | |
65 | +++++++++++++++++++++++++++++++++++++++ | |
66 | ||
67 | :: | |
68 | ||
69 | // a class that has no normal copy semantics | |
70 | class X : boost::noncopyable { public: X* clone() const; ... }; | |
71 | ||
72 | // this will be found by the library by argument dependent lookup (ADL) | |
73 | X* new_clone( const X& x ) | |
74 | { return x.clone(); } | |
75 | ||
76 | // we can now use the interface that requires cloneability | |
77 | ptr_vector<X> vec1, vec2; | |
78 | ... | |
79 | vec2 = vec1.clone(); // 'clone()' requires cloning <g> | |
80 | vec2.insert( vec2.end(), vec1.begin(), vec1.end() ); // inserting always means inserting clones | |
81 | ||
82 | ||
83 | .. _`Example 5`: | |
84 | ||
85 | 5. Objects are cloned before insertion, inserted pointers are owned by the container | |
86 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
87 | ||
88 | :: | |
89 | ||
90 | class X { ... }; // assume 'X' is Cloneable | |
91 | X x; // and 'X' can be stack-allocated | |
92 | ptr_list<X> list; | |
93 | list.push_back( new_clone( x ) ); // insert a clone | |
94 | list.push_back( new X ); // always give the pointer directly to the container to avoid leaks | |
95 | list.push_back( &x ); // don't do this!!! | |
96 | std::auto_ptr<X> p( new X ); | |
97 | list.push_back( p ); // give up ownership | |
98 | BOOST_ASSERT( p.get() == 0 ); | |
99 | ||
100 | ||
101 | .. _`Example 6`: | |
102 | ||
103 | 6. Transferring ownership of a single element | |
104 | +++++++++++++++++++++++++++++++++++++++++++++ | |
105 | ||
106 | :: | |
107 | ||
108 | ptr_deque<T> deq; | |
109 | typedef ptr_deque<T>::auto_type auto_type; | |
110 | ||
111 | // ... fill the container somehow | |
112 | ||
113 | auto_type ptr = deq.release_back(); // remove back element from container and give up ownership | |
114 | auto_type ptr2 = deq.release( deq.begin() + 2 ); // use an iterator to determine the element to release | |
115 | ptr = deq.release_front(); // supported for 'ptr_list' and 'ptr_deque' | |
116 | ||
117 | deq.push_back( ptr.release() ); // give ownership back to the container | |
118 | ||
119 | ||
120 | .. _`Example 7`: | |
121 | ||
122 | 7. Transferring ownership of pointers between different pointer containers | |
123 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
124 | ||
125 | :: | |
126 | ||
127 | ||
128 | ptr_list<X> list; ptr_vector<X> vec; | |
129 | ... | |
130 | // | |
131 | // note: no cloning happens in these examples | |
132 | // | |
133 | list.transfer( list.begin(), vec.begin(), vec ); // make the first element of 'vec' the first element of 'list' | |
134 | vec.transfer( vec.end(), list.begin(), list.end(), list ); // put all the lists element into the vector | |
135 | ||
136 | We can also transfer objects from ``ptr_container<Derived>`` to ``ptr_container<Base>`` without any problems. | |
137 | ||
138 | .. _`Example 8`: | |
139 | ||
140 | ||
141 | ||
142 | 8. Selected test files | |
143 | ++++++++++++++++++++++ | |
144 | ||
145 | :incomplete_type_test.cpp_: Shows how to implement the Composite pattern. | |
146 | :simple_test.cpp_: Shows how the usage of pointer container compares with a | |
147 | container of smart pointers | |
148 | :view_example.cpp_: Shows how to use a pointer container as a view into other container | |
149 | :tree_test.cpp_: Shows how to make a tree-structure | |
150 | :array_test.cpp_: Shows how to make an n-ary tree | |
151 | ||
152 | .. _incomplete_type_test.cpp : ../test/incomplete_type_test.cpp | |
153 | .. _simple_test.cpp : ../test/simple_test.cpp | |
154 | .. _view_example.cpp : ../test/view_example.cpp | |
155 | .. _tree_test.cpp : ../test/tree_test.cpp | |
156 | .. _array_test.cpp : ../test/ptr_array.cpp | |
157 | ||
158 | ||
159 | ||
160 | 9. A large example | |
161 | ++++++++++++++++++ | |
162 | ||
163 | This example shows many of the most common | |
164 | features at work. The example provide lots of comments. | |
165 | The source code can also be found `here <../test/tut1.cpp>`_. | |
166 | ||
167 | .. raw:: html | |
168 | :file: tutorial_example.html | |
169 | ||
170 | .. | |
171 | 10. Changing the Clone Allocator | |
172 | ++++++++++++++++++++++++++++++++ | |
173 | ||
174 | This example shows how we can change | |
175 | the Clone Allocator to use the pointer containers | |
176 | as view into other containers: | |
177 | ||
178 | .. raw:: html | |
179 | :file: tut2.html | |
180 | ||
181 | .. raw:: html | |
182 | ||
183 | <hr> | |
184 | ||
185 | **Navigate:** | |
186 | ||
187 | - `home <ptr_container.html>`_ | |
188 | - `reference <reference.html>`_ | |
189 | ||
190 | .. raw:: html | |
191 | ||
192 | <hr> | |
193 | ||
194 | :Copyright: Thorsten Ottosen 2004-2006. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see LICENSE_1_0.txt__). | |
195 | ||
196 | __ http://www.boost.org/LICENSE_1_0.txt | |
197 | ||
198 |