]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
2 | <html> | |
3 | <head> | |
4 | <title>shared_ptr</title> | |
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | |
6 | </head> | |
7 | <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff"> | |
8 | <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png" | |
9 | width="277" align="middle" border="0">shared_ptr class template</h1> | |
10 | <p><a href="#Introduction">Introduction</a><br> | |
11 | <a href="#BestPractices">Best Practices</a><br> | |
12 | <a href="#Synopsis">Synopsis</a><br> | |
13 | <a href="#Members">Members</a><br> | |
14 | <a href="#functions">Free Functions</a><br> | |
15 | <a href="#example">Example</a><br> | |
16 | <a href="#HandleBody">Handle/Body Idiom</a><br> | |
17 | <a href="#ThreadSafety">Thread Safety</a><br> | |
18 | <a href="#FAQ">Frequently Asked Questions</a><br> | |
19 | <a href="smarttests.htm">Smart Pointer Timings</a><br> | |
20 | <a href="sp_techniques.html">Programming Techniques</a></p> | |
21 | <h2 id="Introduction">Introduction</h2> | |
22 | <p>The <code>shared_ptr</code> class template stores a pointer to a dynamically allocated | |
23 | object, typically with a C++ <em>new-expression</em>. The object pointed to is | |
24 | guaranteed to be deleted when the last <code>shared_ptr</code> pointing to it is | |
25 | destroyed or reset.</p> | |
26 | <blockquote><em>Example:</em><br><pre>shared_ptr<X> p1( new X ); | |
27 | shared_ptr<void> p2( new int(5) ); | |
28 | </pre></blockquote> | |
29 | ||
30 | <p><code>shared_ptr</code> deletes the exact pointer that has been passed at construction time, | |
31 | complete with its original type, regardless of the template parameter. In the second example above, | |
32 | when <code>p2</code> is destroyed or reset, it will call <code>delete</code> on the original <code>int*</code> | |
33 | that has been passed to the constructor, even though <code>p2</code> itself is of type | |
34 | <code>shared_ptr<void></code> and stores a pointer of type <code>void*</code>.</p> | |
35 | ||
36 | <p>Every <code>shared_ptr</code> meets the <code>CopyConstructible</code>, <code>MoveConstructible</code>, | |
37 | <code>CopyAssignable</code> and <code>MoveAssignable</code> | |
38 | requirements of the C++ Standard Library, and can be used in standard | |
39 | library containers. Comparison operators are supplied so that <code>shared_ptr</code> | |
40 | works with the standard library's associative containers.</p> | |
41 | <p>Because the implementation uses reference counting, cycles of <code>shared_ptr</code> instances | |
42 | will not be reclaimed. For example, if <code>main()</code> holds a <code>shared_ptr</code> to | |
43 | <code>A</code>, which directly or indirectly holds a <code>shared_ptr</code> back to <code>A</code>, | |
44 | <code>A</code>'s use count will be 2. Destruction of the original <code>shared_ptr</code> will | |
45 | leave <code>A</code> dangling with a use count of 1. Use <a href="weak_ptr.htm">weak_ptr</a> | |
46 | to "break cycles."</p> | |
47 | <p>The class template is parameterized on <code>T</code>, the type of the object pointed | |
48 | to. <code>shared_ptr</code> and most of its member functions place no | |
49 | requirements on <code>T</code>; it is allowed to be an incomplete type, or | |
50 | <code>void</code>. Member functions that do place additional requirements | |
51 | (<a href="#pointer_constructor">constructors</a>, <a href="#reset">reset</a>) are explicitly | |
52 | documented below.</p> | |
53 | <p><code>shared_ptr<T></code> can be implicitly converted to <code>shared_ptr<U></code> | |
54 | whenever <code>T*</code> can be implicitly converted to <code>U*</code>. | |
55 | In particular, <code>shared_ptr<T></code> is implicitly convertible | |
56 | to <code>shared_ptr<T const></code>, to <code>shared_ptr<U></code> | |
57 | where <code>U</code> is an accessible base of <code>T</code>, and to <code> | |
58 | shared_ptr<void></code>.</p> | |
59 | <p><code>shared_ptr</code> is now part of the C++11 Standard, as <code>std::shared_ptr</code>.</p> | |
60 | <p>Starting with Boost release 1.53, <code>shared_ptr</code> can be used to hold a pointer to a dynamically | |
61 | allocated array. This is accomplished by using an array type (<code>T[]</code> or <code>T[N]</code>) as | |
62 | the template parameter. There is almost no difference between using an unsized array, <code>T[]</code>, | |
63 | and a sized array, <code>T[N]</code>; the latter just enables <code>operator[]</code> to perform a range check | |
64 | on the index.</p> | |
65 | <blockquote><em>Example:</em><br><pre>shared_ptr<double[1024]> p1( new double[1024] ); | |
66 | shared_ptr<double[]> p2( new double[n] ); | |
67 | </pre></blockquote> | |
68 | ||
69 | <h2 id="BestPractices">Best Practices</h2> | |
70 | <p>A simple guideline that nearly eliminates the possibility of memory leaks is: | |
71 | always use a named smart pointer variable to hold the result of <code>new</code>. | |
72 | Every occurence of the <code>new</code> keyword in the code should have the | |
73 | form:</p> | |
74 | <pre>shared_ptr<T> p(new Y);</pre> | |
75 | <p>It is, of course, acceptable to use another smart pointer in place of <code>shared_ptr</code> | |
76 | above; having <code>T</code> and <code>Y</code> be the same type, or | |
77 | passing arguments to <code>Y</code>'s constructor is also OK.</p> | |
78 | <p>If you observe this guideline, it naturally follows that you will have no | |
79 | explicit <code>delete</code> statements; <code>try/catch</code> constructs will | |
80 | be rare.</p> | |
81 | <p>Avoid using unnamed <code>shared_ptr</code> temporaries to save typing; to | |
82 | see why this is dangerous, consider this example:</p> | |
83 | <pre>void f(shared_ptr<int>, int); | |
84 | int g(); | |
85 | ||
86 | void ok() | |
87 | { | |
88 | shared_ptr<int> p( new int(2) ); | |
89 | f( p, g() ); | |
90 | } | |
91 | ||
92 | void bad() | |
93 | { | |
94 | f( shared_ptr<int>( new int(2) ), g() ); | |
95 | } | |
96 | </pre> | |
97 | <p>The function <code>ok</code> follows the guideline to the letter, whereas | |
98 | <code>bad</code> constructs the temporary <code>shared_ptr</code> in place, | |
99 | admitting the possibility of a memory leak. Since function arguments are | |
100 | evaluated in unspecified order, it is possible for <code>new int(2)</code> to | |
101 | be evaluated first, <code>g()</code> second, and we may never get to the | |
102 | <code>shared_ptr</code>constructor if <code>g</code> throws an exception. | |
103 | See <a href="http://www.gotw.ca/gotw/056.htm">Herb Sutter's treatment</a> (also <a href="http://www.cuj.com/reference/articles/2002/0212/0212_sutter.htm"> | |
104 | here</a>) of the issue for more information.</p> | |
105 | <p>The exception safety problem described above may also be eliminated by using | |
106 | the <a href="make_shared.html"><code>make_shared</code></a> | |
107 | or <a href="make_shared.html"><code>allocate_shared</code></a> | |
108 | factory functions defined in <code>boost/make_shared.hpp</code>. | |
109 | These factory functions also provide an efficiency benefit by consolidating allocations.</p> | |
110 | <h2 id="Synopsis">Synopsis</h2> | |
111 | <pre>namespace boost { | |
112 | ||
113 | class bad_weak_ptr: public std::exception; | |
114 | ||
115 | template<class T> class <a href="weak_ptr.htm" >weak_ptr</a>; | |
116 | ||
117 | template<class T> class shared_ptr { | |
118 | ||
119 | public: | |
120 | ||
121 | typedef <em>see below</em> <a href="#element_type" >element_type</a>; | |
122 | ||
123 | <a href="#default_constructor" >shared_ptr</a>(); // never throws | |
124 | <a href="#default_constructor" >shared_ptr</a>(std::nullptr_t); // never throws | |
125 | ||
126 | template<class Y> explicit <a href="#pointer_constructor" >shared_ptr</a>(Y * p); | |
127 | template<class Y, class D> <a href="#deleter_constructor" >shared_ptr</a>(Y * p, D d); | |
128 | template<class Y, class D, class A> <a href="#deleter_constructor" >shared_ptr</a>(Y * p, D d, A a); | |
129 | template<class D> <a href="#deleter_constructor" >shared_ptr</a>(std::nullptr_t p, D d); | |
130 | template<class D, class A> <a href="#deleter_constructor" >shared_ptr</a>(std::nullptr_t p, D d, A a); | |
131 | ||
132 | <a href="#destructor" >~shared_ptr</a>(); // never throws | |
133 | ||
134 | <a href="#copy_constructor" >shared_ptr</a>(shared_ptr const & r); // never throws | |
135 | template<class Y> <a href="#copy_constructor" >shared_ptr</a>(shared_ptr<Y> const & r); // never throws | |
136 | ||
137 | <a href="#move_constructor" >shared_ptr</a>(shared_ptr && r); // never throws | |
138 | template<class Y> <a href="#move_constructor" >shared_ptr</a>(shared_ptr<Y> && r); // never throws | |
139 | ||
140 | template<class Y> <a href="#aliasing_constructor" >shared_ptr</a>(shared_ptr<Y> const & r, element_type * p); // never throws | |
141 | ||
142 | template<class Y> <a href="#aliasing_move_constructor" >shared_ptr</a>(shared_ptr<Y> && r, element_type * p); // never throws | |
143 | ||
144 | template<class Y> explicit <a href="#weak_ptr_constructor" >shared_ptr</a>(<a href="weak_ptr.htm" >weak_ptr</a><Y> const & r); | |
145 | ||
146 | template<class Y> explicit <a href="#auto_ptr_constructor" >shared_ptr</a>(std::auto_ptr<Y> & r); | |
147 | template<class Y> <a href="#auto_ptr_constructor" >shared_ptr</a>(std::auto_ptr<Y> && r); | |
148 | ||
149 | template<class Y, class D> <a href="#unique_ptr_constructor" >shared_ptr</a>(std::unique_ptr<Y, D> && r); | |
150 | ||
151 | shared_ptr & <a href="#assignment" >operator=</a>(shared_ptr const & r); // never throws | |
152 | template<class Y> shared_ptr & <a href="#assignment" >operator=</a>(shared_ptr<Y> const & r); // never throws | |
153 | ||
154 | shared_ptr & <a href="#assignment" >operator=</a>(shared_ptr const && r); // never throws | |
155 | template<class Y> shared_ptr & <a href="#assignment" >operator=</a>(shared_ptr<Y> const && r); // never throws | |
156 | ||
157 | template<class Y> shared_ptr & <a href="#assignment" >operator=</a>(std::auto_ptr<Y> & r); | |
158 | template<class Y> shared_ptr & <a href="#assignment" >operator=</a>(std::auto_ptr<Y> && r); | |
159 | ||
160 | template<class Y, class D> shared_ptr & <a href="#assignment" >operator=</a>(std::unique_ptr<Y, D> && r); | |
161 | ||
162 | shared_ptr & <a href="#assignment" >operator=</a>(std::nullptr_t); // never throws | |
163 | ||
164 | void <a href="#reset" >reset</a>(); // never throws | |
165 | ||
166 | template<class Y> void <a href="#reset" >reset</a>(Y * p); | |
167 | template<class Y, class D> void <a href="#reset" >reset</a>(Y * p, D d); | |
168 | template<class Y, class D, class A> void <a href="#reset" >reset</a>(Y * p, D d, A a); | |
169 | ||
170 | template<class Y> void <a href="#reset" >reset</a>(shared_ptr<Y> const & r, element_type * p); // never throws | |
171 | ||
172 | T & <a href="#indirection" >operator*</a>() const; // never throws; only valid when T is not an array type | |
173 | T * <a href="#indirection" >operator-></a>() const; // never throws; only valid when T is not an array type | |
174 | ||
175 | element_type & <a href="#indirection" >operator[]</a>(std::ptrdiff_t i) const; // never throws; only valid when T is an array type | |
176 | ||
177 | element_type * <a href="#get" >get</a>() const; // never throws | |
178 | ||
179 | bool <a href="#unique" >unique</a>() const; // never throws | |
180 | long <a href="#use_count" >use_count</a>() const; // never throws | |
181 | ||
182 | explicit <a href="#conversions" >operator bool</a>() const; // never throws | |
183 | ||
184 | void <a href="#swap" >swap</a>(shared_ptr & b); // never throws | |
185 | ||
186 | template<class Y> bool <a href="#owner_before" >owner_before</a>(shared_ptr<Y> const & rhs) const; // never throws | |
187 | template<class Y> bool <a href="#owner_before" >owner_before</a>(weak_ptr<Y> const & rhs) const; // never throws | |
188 | }; | |
189 | ||
190 | template<class T, class U> | |
191 | bool <a href="#comparison" >operator==</a>(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws | |
192 | ||
193 | template<class T, class U> | |
194 | bool <a href="#comparison" >operator!=</a>(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws | |
195 | ||
196 | template<class T, class U> | |
197 | bool <a href="#comparison" >operator<</a>(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws | |
198 | ||
199 | template<class T> | |
200 | bool <a href="#comparison" >operator==</a>(shared_ptr<T> const & p, std::nullptr_t); // never throws | |
201 | ||
202 | template<class T> | |
203 | bool <a href="#comparison" >operator==</a>(std::nullptr_t, shared_ptr<T> const & p); // never throws | |
204 | ||
205 | template<class T> | |
206 | bool <a href="#comparison" >operator!=</a>(shared_ptr<T> const & p, std::nullptr_t); // never throws | |
207 | ||
208 | template<class T> | |
209 | bool <a href="#comparison" >operator!=</a>(std::nullptr_t, shared_ptr<T> const & p); // never throws | |
210 | ||
211 | template<class T> void <a href="#free-swap" >swap</a>(shared_ptr<T> & a, shared_ptr<T> & b); // never throws | |
212 | ||
213 | template<class T> typename shared_ptr<T>::element_type * <a href="#get_pointer" >get_pointer</a>(shared_ptr<T> const & p); // never throws | |
214 | ||
215 | template<class T, class U> | |
216 | shared_ptr<T> <a href="#static_pointer_cast" >static_pointer_cast</a>(shared_ptr<U> const & r); // never throws | |
217 | ||
218 | template<class T, class U> | |
219 | shared_ptr<T> <a href="#const_pointer_cast" >const_pointer_cast</a>(shared_ptr<U> const & r); // never throws | |
220 | ||
221 | template<class T, class U> | |
222 | shared_ptr<T> <a href="#dynamic_pointer_cast" >dynamic_pointer_cast</a>(shared_ptr<U> const & r); // never throws | |
223 | ||
224 | template<class T, class U> | |
225 | shared_ptr<T> <a href="#reinterpret_pointer_cast" >reinterpret_pointer_cast</a>(shared_ptr<U> const & r); // never throws | |
226 | ||
227 | template<class E, class T, class Y> | |
228 | std::basic_ostream<E, T> & <a href="#insertion-operator" >operator<<</a> (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p); | |
229 | ||
230 | template<class D, class T> | |
231 | D * <a href="#get_deleter">get_deleter</a>(shared_ptr<T> const & p); | |
232 | }</pre> | |
233 | <h2 id="Members">Members</h2> | |
234 | <h3 id="element_type">element_type</h3> | |
235 | <pre>typedef <em>...</em> element_type;</pre> | |
236 | <blockquote> | |
237 | <p><code>element_type</code> is <code>T</code> when <code>T</code> is not an array type, | |
238 | and <code>U</code> when <code>T</code> is <code>U[]</code> or <code>U[N]</code>.</p> | |
239 | </blockquote> | |
240 | <h3 id="default_constructor">default constructor</h3> | |
241 | <pre>shared_ptr(); // never throws | |
242 | shared_ptr(std::nullptr_t); // never throws</pre> | |
243 | <blockquote> | |
244 | <p><b>Effects:</b> Constructs an <em>empty</em> <code>shared_ptr</code>.</p> | |
245 | <p><b>Postconditions:</b> <code>use_count() == 0 && get() == 0</code>.</p> | |
246 | <p><b>Throws:</b> nothing.</p> | |
247 | </blockquote> | |
248 | <p><em>[The nothrow guarantee is important, since <code>reset()</code> is specified | |
249 | in terms of the default constructor; this implies that the constructor must not | |
250 | allocate memory.]</em></p> | |
251 | <h3 id="pointer_constructor">pointer constructor</h3> | |
252 | <pre>template<class Y> explicit shared_ptr(Y * p);</pre> | |
253 | <blockquote> | |
254 | <p><b>Requirements:</b> | |
255 | <code>Y</code> must be a complete type. | |
256 | The expression <code>delete[] p</code>, when <code>T</code> is an array type, or <code>delete p</code>, | |
257 | when <code>T</code> is not an array type, | |
258 | must be well-formed, must not invoke undefined behavior, and must not throw exceptions. | |
259 | When <code>T</code> is <code>U[N]</code>, <code>Y (*) [N]</code> must be convertible to <code>T*</code>; | |
260 | when <code>T</code> is <code>U[]</code>, <code>Y (*) []</code> must be convertible to <code>T*</code>; | |
261 | otherwise, <code>Y*</code> must be convertible to <code>T*</code>. | |
262 | </p> | |
263 | <p><b>Effects:</b> | |
264 | When <code>T</code> is not an array type, constructs a <code>shared_ptr</code> that <em>owns</em> | |
265 | the pointer <code>p</code>. | |
266 | Otherwise, constructs a <code>shared_ptr</code> that <em>owns</em> | |
267 | <code>p</code> and a deleter of an unspecified type that calls <code>delete[] p</code>.</p> | |
268 | <p><b>Postconditions:</b> <code>use_count() == 1 && get() == p</code>. | |
269 | If <code>T</code> is not an array type and <code>p</code> is unambiguously convertible to <code> | |
270 | <a href="enable_shared_from_this.html">enable_shared_from_this</a><V>*</code> | |
271 | for some <code>V</code>, <code>p->shared_from_this()</code> returns a copy of | |
272 | <code>*this</code>.</p> | |
273 | <p><b>Throws:</b> <code>std::bad_alloc</code>, or an implementation-defined | |
274 | exception when a resource other than memory could not be obtained.</p> | |
275 | <p><b>Exception safety:</b> If an exception is thrown, the constructor calls | |
276 | <code>delete[] p</code>, when <code>T</code> is an array type, | |
277 | or <code>delete p</code>, when <code>T</code> is not an array type.</p> | |
278 | <p><b>Notes:</b> <code>p</code> must be a pointer to an object that was | |
279 | allocated via a C++ <code>new</code> expression or be 0. The postcondition that <a href="#use_count"> | |
280 | use count</a> is 1 holds even if <code>p</code> is 0; invoking <code>delete</code> | |
281 | on a pointer that has a value of 0 is harmless.</p> | |
282 | </blockquote> | |
283 | <p><em>[This constructor is a template in order to remember the actual | |
284 | pointer type passed. The destructor will call <code>delete</code> with the | |
285 | same pointer, complete with its original type, even when <code>T</code> does | |
286 | not have a virtual destructor, or is <code>void</code>.]</em></p> | |
287 | <h3 id="deleter_constructor">constructors taking a deleter</h3> | |
288 | <pre>template<class Y, class D> shared_ptr(Y * p, D d); | |
289 | template<class Y, class D, class A> shared_ptr(Y * p, D d, A a); | |
290 | template<class D> shared_ptr(std::nullptr_t p, D d); | |
291 | template<class D, class A> shared_ptr(std::nullptr_t p, D d, A a);</pre> | |
292 | <blockquote> | |
293 | <p><b>Requirements:</b> | |
294 | <code>D</code> must be <code>CopyConstructible</code>. The copy constructor and destructor | |
295 | of <code>D</code> must not throw. The expression <code>d(p)</code> must be | |
296 | well-formed, must not invoke undefined behavior, and must not throw exceptions. | |
297 | <code>A</code> must be an <em>Allocator</em>, as described in section 20.1.5 | |
298 | (<code>Allocator requirements</code>) of the C++ Standard. | |
299 | When <code>T</code> is <code>U[N]</code>, <code>Y (*) [N]</code> must be convertible to <code>T*</code>; | |
300 | when <code>T</code> is <code>U[]</code>, <code>Y (*) []</code> must be convertible to <code>T*</code>; | |
301 | otherwise, <code>Y*</code> must be convertible to <code>T*</code>. | |
302 | </p> | |
303 | <p><b>Effects:</b> Constructs a <code>shared_ptr</code> that <em>owns</em> the pointer <code> | |
304 | p</code> and the deleter <code>d</code>. The constructors taking an allocator <code>a</code> | |
305 | allocate memory using a copy of <code>a</code>.</p> | |
306 | <p><b>Postconditions:</b> <code>use_count() == 1 && get() == p</code>. | |
307 | If <code>T</code> is not an array type and <code>p</code> is unambiguously convertible to <code> | |
308 | <a href="enable_shared_from_this.html">enable_shared_from_this</a><V>*</code> | |
309 | for some <code>V</code>, <code>p->shared_from_this()</code> returns a copy of | |
310 | <code>*this</code>.</p> | |
311 | <p><b>Throws:</b> <code>std::bad_alloc</code>, or an implementation-defined | |
312 | exception when a resource other than memory could not be obtained.</p> | |
313 | <p><b>Exception safety:</b> If an exception is thrown, <code>d(p)</code> is called.</p> | |
314 | <p><b>Notes:</b> When the the time comes to delete the object pointed to by <code>p</code>, | |
315 | the stored copy of <code>d</code> is invoked with the stored copy of <code>p</code> | |
316 | as an argument.</p> | |
317 | </blockquote> | |
318 | <p><em>[Custom deallocators allow a factory function returning a <code>shared_ptr</code> | |
319 | to insulate the user from its memory allocation strategy. Since the deallocator | |
320 | is not part of the type, changing the allocation strategy does not break source | |
321 | or binary compatibility, and does not require a client recompilation. For | |
322 | example, a "no-op" deallocator is useful when returning a <code>shared_ptr</code> | |
323 | to a statically allocated object, and other variations allow a <code>shared_ptr</code> | |
324 | to be used as a wrapper for another smart pointer, easing interoperability.</em></p> | |
325 | <p><em>The support for custom deallocators does not impose significant overhead. Other <code> | |
326 | shared_ptr</code> features still require a deallocator to be kept.</em></p> | |
327 | <p><em>The requirement that the copy constructor of <code>D</code> does not throw comes from | |
328 | the pass by value. If the copy constructor throws, the pointer would leak.]</em></p> | |
329 | <h3 id="copy_constructor">copy and converting constructors</h3> | |
330 | <pre>shared_ptr(shared_ptr const & r); // never throws | |
331 | template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws</pre> | |
332 | <blockquote> | |
333 | <p><b>Requires:</b> <code>Y*</code> should be convertible to <code>T*</code>.</p> | |
334 | <p><b>Effects:</b> If <code>r</code> is <em>empty</em>, constructs an <em>empty</em> <code>shared_ptr</code>; | |
335 | otherwise, constructs a <code>shared_ptr</code> that <em>shares ownership</em> with <code>r</code>.</p> | |
336 | <p><b>Postconditions:</b> <code>get() == r.get() && use_count() == | |
337 | r.use_count()</code>.</p> | |
338 | <p><b>Throws:</b> nothing.</p> | |
339 | </blockquote> | |
340 | <h3 id="move_constructor">move constructors</h3> | |
341 | <pre>shared_ptr(shared_ptr && r); // never throws | |
342 | template<class Y> shared_ptr(shared_ptr<Y> && r); // never throws</pre> | |
343 | <blockquote> | |
344 | <p><b>Requires:</b> <code>Y*</code> should be convertible to <code>T*</code>.</p> | |
345 | <p><b>Effects:</b> Move-constructs a <code>shared_ptr</code> from <code>r</code>.</p> | |
346 | <p><b>Postconditions:</b> <code>*this</code> contains the old value of <code>r</code>. <code>r</code> is <em>empty</em> and <code>r.get() == 0</code>.</p> | |
347 | <p><b>Throws:</b> nothing.</p> | |
348 | </blockquote> | |
349 | <h3 id="aliasing_constructor">aliasing constructor</h3> | |
350 | <pre>template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p); // never throws</pre> | |
351 | <blockquote> | |
352 | <p><b>Effects:</b> constructs a <code>shared_ptr</code> that <em>shares ownership</em> with | |
353 | <code>r</code> and stores <code>p</code>.</p> | |
354 | <p><b>Postconditions:</b> <code>get() == p && use_count() == r.use_count()</code>.</p> | |
355 | <p><b>Throws:</b> nothing.</p> | |
356 | </blockquote> | |
357 | <h3 id="aliasing_move_constructor">aliasing move constructor</h3> | |
358 | <pre>template<class Y> shared_ptr(shared_ptr<Y> && r, element_type * p); // never throws</pre> | |
359 | <blockquote> | |
360 | <p> | |
361 | <b>Effects:</b> Move-constructs a <code>shared_ptr</code> from <code>r</code>, while | |
362 | storing <code>p</code> instead. | |
363 | </p> | |
364 | <p><b>Postconditions:</b> <code>get() == p</code> and <code>use_count()</code> equals the old count of <code>r</code>. <code>r</code> is <em>empty</em> and <code>r.get() == 0</code>.</p> | |
365 | <p><b>Throws:</b> nothing.</p> | |
366 | </blockquote> | |
367 | <h3 id="weak_ptr_constructor">weak_ptr constructor</h3> | |
368 | <pre>template<class Y> explicit shared_ptr(<a href="weak_ptr.htm" >weak_ptr</a><Y> const & r);</pre> | |
369 | <blockquote> | |
370 | <p><b>Requires:</b> <code>Y*</code> should be convertible to <code>T*</code>.</p> | |
371 | <p><b>Effects:</b> Constructs a <code>shared_ptr</code> that <em>shares ownership</em> with | |
372 | <code>r</code> and stores a copy of the pointer stored in <code>r</code>.</p> | |
373 | <p><b>Postconditions:</b> <code>use_count() == r.use_count()</code>.</p> | |
374 | <p><b>Throws:</b> <code>bad_weak_ptr</code> when <code>r.use_count() == 0</code>.</p> | |
375 | <p><b>Exception safety:</b> If an exception is thrown, the constructor has no | |
376 | effect.</p> | |
377 | </blockquote> | |
378 | <h3 id="auto_ptr_constructor">auto_ptr constructors</h3> | |
379 | <pre>template<class Y> shared_ptr(std::auto_ptr<Y> & r); | |
380 | template<class Y> shared_ptr(std::auto_ptr<Y> && r);</pre> | |
381 | <blockquote> | |
382 | <p><b>Requires:</b> <code>Y*</code> should be convertible to <code>T*</code>.</p> | |
383 | <p><b>Effects:</b> Constructs a <code>shared_ptr</code>, as if by storing a copy of <code>r.release()</code>.</p> | |
384 | <p><b>Postconditions:</b> <code>use_count() == 1</code>.</p> | |
385 | <p><b>Throws:</b> <code>std::bad_alloc</code>, or an implementation-defined | |
386 | exception when a resource other than memory could not be obtained.</p> | |
387 | <p><b>Exception safety:</b> If an exception is thrown, the constructor has no | |
388 | effect.</p> | |
389 | </blockquote> | |
390 | <h3 id="unique_ptr_constructor">unique_ptr constructor</h3> | |
391 | <pre>template<class Y, class D> shared_ptr(std::unique_ptr<Y, D> && r);</pre> | |
392 | <blockquote> | |
393 | <p><b>Requires:</b> <code>Y*</code> should be convertible to <code>T*</code>.</p> | |
394 | <p><b>Effects:</b> | |
395 | Equivalent to <code>shared_ptr(r.release(), r.get_deleter())</code> when <code>D</code> is not a reference type. | |
396 | Otherwise, equivalent to <code>shared_ptr(r.release(), <em>del</em>)</code>, where <em>del</em> is a deleter | |
397 | that stores the reference <code>rd</code> returned from <code>r.get_deleter()</code> and <code>del(p)</code> calls <code>rd(p)</code>.</p> | |
398 | <p><b>Postconditions:</b> <code>use_count() == 1</code>.</p> | |
399 | <p><b>Throws:</b> <code>std::bad_alloc</code>, or an implementation-defined | |
400 | exception when a resource other than memory could not be obtained.</p> | |
401 | <p><b>Exception safety:</b> If an exception is thrown, the constructor has no | |
402 | effect.</p> | |
403 | </blockquote> | |
404 | <h3 id="destructor">destructor</h3> | |
405 | <pre>~shared_ptr(); // never throws</pre> | |
406 | <blockquote> | |
407 | <p><b>Effects:</b></p> | |
408 | <ul> | |
409 | <li> | |
410 | If <code>*this</code> is <em>empty</em>, or <em>shares ownership</em> with | |
411 | another <code>shared_ptr</code> instance (<code>use_count() > 1</code>), | |
412 | there are no side effects.</li> | |
413 | <li> | |
414 | Otherwise, if <code>*this</code> <em>owns</em> a pointer <code>p</code> | |
415 | and a deleter <code>d</code>, <code>d(p)</code> | |
416 | is called.</li> | |
417 | <li> | |
418 | Otherwise, <code>*this</code> <em>owns</em> a pointer <code>p</code>, | |
419 | and <code>delete p</code> is called.</li> | |
420 | </ul> | |
421 | <p><b>Throws:</b> nothing.</p> | |
422 | </blockquote> | |
423 | <h3 id="assignment">assignment</h3> | |
424 | <pre>shared_ptr & operator=(shared_ptr const & r); // never throws | |
425 | template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r); // never throws | |
426 | template<class Y> shared_ptr & operator=(std::auto_ptr<Y> & r);</pre> | |
427 | <blockquote> | |
428 | <p><b>Effects:</b> Equivalent to <code>shared_ptr(r).swap(*this)</code>.</p> | |
429 | <p><b>Returns:</b> <code>*this</code>.</p> | |
430 | <p><b>Notes:</b> The use count updates caused by the temporary object construction | |
431 | and destruction are not considered observable side effects, and the | |
432 | implementation is free to meet the effects (and the implied guarantees) via | |
433 | different means, without creating a temporary. In particular, in the example:</p> | |
434 | <pre>shared_ptr<int> p(new int); | |
435 | shared_ptr<void> q(p); | |
436 | p = p; | |
437 | q = p; | |
438 | </pre> | |
439 | <p>both assignments may be no-ops.</p> | |
440 | </blockquote> | |
441 | <pre>shared_ptr & operator=(shared_ptr && r); // never throws | |
442 | template<class Y> shared_ptr & operator=(shared_ptr<Y> && r); // never throws | |
443 | template<class Y> shared_ptr & operator=(std::auto_ptr<Y> && r); | |
444 | template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y, D> && r);</pre> | |
445 | <blockquote> | |
446 | <p><b>Effects:</b> Equivalent to <code>shared_ptr(std::move(r)).swap(*this)</code>.</p> | |
447 | <p><b>Returns:</b> <code>*this</code>.</p> | |
448 | </blockquote> | |
449 | <pre>shared_ptr & operator=(std::nullptr_t); // never throws</pre> | |
450 | <blockquote> | |
451 | <p><b>Effects:</b> Equivalent to <code>shared_ptr().swap(*this)</code>.</p> | |
452 | <p><b>Returns:</b> <code>*this</code>.</p> | |
453 | </blockquote> | |
454 | <h3 id="reset">reset</h3> | |
455 | <pre>void reset(); // never throws</pre> | |
456 | <blockquote> | |
457 | <p><b>Effects:</b> Equivalent to <code>shared_ptr().swap(*this)</code>.</p> | |
458 | </blockquote> | |
459 | <pre>template<class Y> void reset(Y * p);</pre> | |
460 | <blockquote> | |
461 | <p><b>Effects:</b> Equivalent to <code>shared_ptr(p).swap(*this)</code>.</p> | |
462 | </blockquote> | |
463 | <pre>template<class Y, class D> void reset(Y * p, D d);</pre> | |
464 | <blockquote> | |
465 | <p><b>Effects:</b> Equivalent to <code>shared_ptr(p, d).swap(*this)</code>.</p> | |
466 | </blockquote> | |
467 | <pre>template<class Y, class D, class A> void reset(Y * p, D d, A a);</pre> | |
468 | <blockquote> | |
469 | <p><b>Effects:</b> Equivalent to <code>shared_ptr(p, d, a).swap(*this)</code>.</p> | |
470 | </blockquote> | |
471 | <pre>template<class Y> void reset(shared_ptr<Y> const & r, element_type * p); // never throws</pre> | |
472 | <blockquote> | |
473 | <p><b>Effects:</b> Equivalent to <code>shared_ptr(r, p).swap(*this)</code>.</p> | |
474 | </blockquote> | |
475 | <h3 id="indirection">indirection</h3> | |
476 | <pre>T & operator*() const; // never throws</pre> | |
477 | <blockquote> | |
478 | <p><b>Requirements:</b> <code>T</code> should not be an array type. The stored pointer must not be 0.</p> | |
479 | <p><b>Returns:</b> a reference to the object pointed to by the stored pointer.</p> | |
480 | <p><b>Throws:</b> nothing.</p> | |
481 | </blockquote> | |
482 | <pre>T * operator->() const; // never throws</pre> | |
483 | <blockquote> | |
484 | <p><b>Requirements:</b> <code>T</code> should not be an array type. The stored pointer must not be 0.</p> | |
485 | <p><b>Returns:</b> the stored pointer.</p> | |
486 | <p><b>Throws:</b> nothing.</p> | |
487 | </blockquote> | |
488 | <pre>element_type & operator[](std::ptrdiff_t i) const; // never throws</pre> | |
489 | <blockquote> | |
490 | <p><b>Requirements:</b> <code>T</code> should be an array type. The stored pointer must not be 0. | |
491 | <code>i >= 0</code>. If <code>T</code> is <code>U[N]</code>, <code>i < N</code>.</p> | |
492 | <p><b>Returns:</b> <code>get()[i]</code>.</p> | |
493 | <p><b>Throws:</b> nothing.</p> | |
494 | </blockquote> | |
495 | <h3 id="get">get</h3> | |
496 | <pre>element_type * get() const; // never throws</pre> | |
497 | <blockquote> | |
498 | <p><b>Returns:</b> the stored pointer.</p> | |
499 | <p><b>Throws:</b> nothing.</p> | |
500 | </blockquote> | |
501 | <h3 id="unique">unique</h3> | |
502 | <pre>bool unique() const; // never throws</pre> | |
503 | <blockquote> | |
504 | <p><b>Returns:</b> <code>use_count() == 1</code>.</p> | |
505 | <p><b>Throws:</b> nothing.</p> | |
506 | <p><b>Notes:</b> <code>unique()</code> may be faster than <code>use_count()</code>. | |
507 | If you are using <code>unique()</code> to implement copy on write, do not rely | |
508 | on a specific value when the stored pointer is zero.</p> | |
509 | </blockquote> | |
510 | <h3 id="use_count">use_count</h3> | |
511 | <pre>long use_count() const; // never throws</pre> | |
512 | <blockquote> | |
513 | <p><b>Returns:</b> the number of <code>shared_ptr</code> objects, <code>*this</code> included, | |
514 | that <i>share ownership</i> with <code>*this</code>, or 0 when <code>*this</code> | |
515 | is <em>empty</em>.</p> | |
516 | <p><b>Throws:</b> nothing.</p> | |
517 | <p><b>Notes:</b> <code>use_count()</code> is not necessarily efficient. Use only | |
518 | for debugging and testing purposes, not for production code.</p> | |
519 | </blockquote> | |
520 | <h3 id="conversions">conversions</h3> | |
521 | <pre>explicit operator bool() const; // never throws</pre> | |
522 | <blockquote> | |
523 | <p><b>Returns:</b> <code>get() != 0</code>.</p> | |
524 | <p><b>Throws:</b> nothing.</p> | |
525 | <p><b>Notes:</b> This conversion operator allows <code>shared_ptr</code> objects to be | |
526 | used in boolean contexts, like <code>if(p && p->valid()) {}</code>.</p> | |
527 | </blockquote> | |
528 | <p><em>[The conversion to bool is not merely syntactic sugar. It allows <code>shared_ptr</code>s | |
529 | to be declared in conditions when using <a href="#dynamic_pointer_cast">dynamic_pointer_cast</a> | |
530 | or <a href="weak_ptr.htm#lock">weak_ptr::lock</a>.]</em></p> | |
531 | <h3 id="swap">swap</h3> | |
532 | <pre>void swap(shared_ptr & b); // never throws</pre> | |
533 | <blockquote> | |
534 | <p><b>Effects:</b> Exchanges the contents of the two smart pointers.</p> | |
535 | <p><b>Throws:</b> nothing.</p> | |
536 | </blockquote> | |
537 | <h3 id="owner_before">swap</h3> | |
538 | <pre>template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const; // never throws | |
539 | template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const; // never throws</pre> | |
540 | <blockquote> | |
541 | <p><b>Effects:</b> See the description of <a href="#comparison"><code>operator<</code></a>.</p> | |
542 | <p><b>Throws:</b> nothing.</p> | |
543 | </blockquote> | |
544 | <h2 id="functions">Free Functions</h2> | |
545 | <h3 id="comparison">comparison</h3> | |
546 | <pre>template<class T, class U> | |
547 | bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws</pre> | |
548 | <blockquote> | |
549 | <p><b>Returns:</b> <code>a.get() == b.get()</code>.</p> | |
550 | <p><b>Throws:</b> nothing.</p> | |
551 | </blockquote> | |
552 | <pre>template<class T, class U> | |
553 | bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws</pre> | |
554 | <blockquote> | |
555 | <p><b>Returns:</b> <code>a.get() != b.get()</code>.</p> | |
556 | <p><b>Throws:</b> nothing.</p> | |
557 | </blockquote> | |
558 | <pre>template<class T> | |
559 | bool operator==(shared_ptr<T> const & p, std::nullptr_t); // never throws | |
560 | template<class T> | |
561 | bool operator==(std::nullptr_t, shared_ptr<T> const & p); // never throws</pre> | |
562 | <blockquote> | |
563 | <p><b>Returns:</b> <code>p.get() == 0</code>.</p> | |
564 | <p><b>Throws:</b> nothing.</p> | |
565 | </blockquote> | |
566 | <pre>template<class T> | |
567 | bool operator!=(shared_ptr<T> const & p, std::nullptr_t); // never throws | |
568 | template<class T> | |
569 | bool operator!=(std::nullptr_t, shared_ptr<T> const & p); // never throws</pre> | |
570 | <blockquote> | |
571 | <p><b>Returns:</b> <code>p.get() != 0</code>.</p> | |
572 | <p><b>Throws:</b> nothing.</p> | |
573 | </blockquote> | |
574 | <pre>template<class T, class U> | |
575 | bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws</pre> | |
576 | <blockquote> | |
577 | <p><b>Returns:</b> an unspecified value such that</p> | |
578 | <ul> | |
579 | <li> | |
580 | <code>operator<</code> is a strict weak ordering as described in section 25.3 <code>[lib.alg.sorting]</code> | |
581 | of the C++ standard;</li> | |
582 | <li> | |
583 | under the equivalence relation defined by <code>operator<</code>, <code>!(a | |
584 | < b) && !(b < a)</code>, two <code>shared_ptr</code> instances | |
585 | are equivalent if and only if they <em>share ownership</em> or are both <em>empty</em>.</li></ul> | |
586 | <p><b>Throws:</b> nothing.</p> | |
587 | <p><b>Notes:</b> Allows <code>shared_ptr</code> objects to be used as keys in | |
588 | associative containers.</p> | |
589 | </blockquote> | |
590 | <p><em>[<code>Operator<</code> has been preferred over a <code>std::less</code> | |
591 | specialization for consistency and legality reasons, as <code>std::less</code> | |
592 | is required to return the results of <code>operator<</code>, and many | |
593 | standard algorithms use <code>operator<</code> instead of <code>std::less</code> | |
594 | for comparisons when a predicate is not supplied. Composite objects, like <code>std::pair</code>, | |
595 | also implement their <code>operator<</code> in terms of their contained | |
596 | subobjects' <code>operator<</code>.</em></p> | |
597 | <p><em>The rest of the comparison operators are omitted by design.]</em></p> | |
598 | <h3 id="free-swap">swap</h3> | |
599 | <pre>template<class T> | |
600 | void swap(shared_ptr<T> & a, shared_ptr<T> & b); // never throws</pre> | |
601 | <blockquote> | |
602 | <p><b>Effects:</b> Equivalent to <code>a.swap(b)</code>.</p> | |
603 | <p><b>Throws:</b> nothing.</p> | |
604 | <p><b>Notes:</b> Matches the interface of <code>std::swap</code>. Provided as an aid to | |
605 | generic programming.</p> | |
606 | </blockquote> | |
607 | <p><em>[<code>swap</code> is defined in the same namespace as <code>shared_ptr</code> | |
608 | as this is currently the only legal way to supply a <code>swap</code> function | |
609 | that has a chance to be used by the standard library.]</em></p> | |
610 | <h3 id="get_pointer">get_pointer</h3> | |
611 | <pre>template<class T> | |
612 | typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p); // never throws</pre> | |
613 | <blockquote> | |
614 | <p><b>Returns:</b> <code>p.get()</code>.</p> | |
615 | <p><b>Throws:</b> nothing.</p> | |
616 | <p><b>Notes:</b> Provided as an aid to generic programming. Used by <a href="../bind/mem_fn.html"> | |
617 | mem_fn</a>.</p> | |
618 | </blockquote> | |
619 | <h3 id="static_pointer_cast">static_pointer_cast</h3> | |
620 | <pre>template<class T, class U> | |
621 | shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r); // never throws</pre> | |
622 | <blockquote> | |
623 | <p><b>Requires:</b> The expression <code>static_cast<T*>( (U*)0 )</code> | |
624 | must be well-formed.</p> | |
625 | <p><b>Returns:</b> <code>shared_ptr<T>( r, static_cast<typename shared_ptr<T>::element_type*>(r.get()) )</code>.</p> | |
626 | <p><b>Throws:</b> nothing.</p> | |
627 | <p><b>Notes:</b> the seemingly equivalent expression | |
628 | <code>shared_ptr<T>(static_cast<T*>(r.get()))</code> | |
629 | will eventually result in undefined behavior, attempting to delete the same | |
630 | object twice.</p> | |
631 | </blockquote> | |
632 | <h3 id="const_pointer_cast">const_pointer_cast</h3> | |
633 | <pre>template<class T, class U> | |
634 | shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r); // never throws</pre> | |
635 | <blockquote> | |
636 | <p><b>Requires:</b> The expression <code>const_cast<T*>( (U*)0 )</code> | |
637 | must be well-formed.</p> | |
638 | <p><b>Returns:</b> <code>shared_ptr<T>( r, const_cast<typename shared_ptr<T>::element_type*>(r.get()) )</code>.</p> | |
639 | <p><b>Throws:</b> nothing.</p> | |
640 | </blockquote> | |
641 | <h3 id="dynamic_pointer_cast">dynamic_pointer_cast</h3> | |
642 | <pre>template<class T, class U> | |
643 | shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r);</pre> | |
644 | <blockquote> | |
645 | <p><b>Requires:</b> The expression <code>dynamic_cast<T*>( (U*)0 )</code> | |
646 | must be well-formed.</p> | |
647 | <p><b>Returns:</b></p> | |
648 | <ul> | |
649 | <li> | |
650 | When <code>dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())</code> returns a nonzero value <code>p</code>, | |
651 | <code>shared_ptr<T>(r, p)</code>;</li> | |
652 | <li> | |
653 | Otherwise, <code>shared_ptr<T>()</code>.</li></ul> | |
654 | <p><b>Throws:</b> nothing.</p> | |
655 | </blockquote> | |
656 | <h3 id="reinterpret_pointer_cast">reinterpret_pointer_cast</h3> | |
657 | <pre>template<class T, class U> | |
658 | shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U> const & r); // never throws</pre> | |
659 | <blockquote> | |
660 | <p><b>Requires:</b> The expression <code>reinterpret_cast<T*>( (U*)0 )</code> | |
661 | must be well-formed.</p> | |
662 | <p><b>Returns:</b> <code>shared_ptr<T>( r, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get()) )</code>.</p> | |
663 | <p><b>Throws:</b> nothing.</p> | |
664 | </blockquote> | |
665 | <h3 id="insertion-operator">operator<<</h3> | |
666 | <pre>template<class E, class T, class Y> | |
667 | std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p);</pre> | |
668 | <blockquote> | |
669 | <p><b>Effects:</b> <code>os << p.get();</code>.</p> | |
670 | <p><b>Returns:</b> <code>os</code>.</p> | |
671 | </blockquote> | |
672 | <h3 id="get_deleter">get_deleter</h3> | |
673 | <pre>template<class D, class T> | |
674 | D * get_deleter(shared_ptr<T> const & p);</pre> | |
675 | <blockquote> | |
676 | <p><b>Returns:</b> If <code>*this</code> <em>owns</em> a deleter <code>d</code> | |
677 | of type (cv-unqualified) <code>D</code>, returns <code>&d</code>; | |
678 | otherwise returns 0.</p> | |
679 | <p><b>Throws:</b> nothing.</p> | |
680 | </blockquote> | |
681 | <h2 id="example">Example</h2> | |
682 | <p>See <a href="example/shared_ptr_example.cpp">shared_ptr_example.cpp</a> for a | |
683 | complete example program. The program builds a <code>std::vector</code> and <code>std::set</code> | |
684 | of <code>shared_ptr</code> objects.</p> | |
685 | <p>Note that after the containers have been populated, some of the <code>shared_ptr</code> | |
686 | objects will have a use count of 1 rather than a use count of 2, since the set | |
687 | is a <code>std::set</code> rather than a <code>std::multiset</code>, and thus does not | |
688 | contain duplicate entries. Furthermore, the use count may be even higher at | |
689 | various times while <code>push_back</code> and <code>insert</code> container operations are | |
690 | performed. More complicated yet, the container operations may throw exceptions | |
691 | under a variety of circumstances. Getting the memory management and exception | |
692 | handling in this example right without a smart pointer would be a nightmare.</p> | |
693 | <h2 id="HandleBody">Handle/Body Idiom</h2> | |
694 | <p>One common usage of <code>shared_ptr</code> is to implement a handle/body (also called | |
695 | pimpl) idiom which avoids exposing the body (implementation) in the header | |
696 | file.</p> | |
697 | <p>The <a href="example/shared_ptr_example2_test.cpp">shared_ptr_example2_test.cpp</a> | |
698 | sample program includes a header file, <a href="example/shared_ptr_example2.hpp">shared_ptr_example2.hpp</a>, | |
699 | which uses a <code>shared_ptr</code> to an incomplete type to hide the | |
700 | implementation. The instantiation of member functions which require a complete | |
701 | type occurs in the <a href="example/shared_ptr_example2.cpp">shared_ptr_example2.cpp</a> | |
702 | implementation file. Note that there is no need for an explicit destructor. | |
703 | Unlike <code>~scoped_ptr</code>, <code>~shared_ptr</code> does not require that <code>T</code> be a complete | |
704 | type.</p> | |
705 | <h2 id="ThreadSafety">Thread Safety</h2> | |
706 | <p><code>shared_ptr</code> objects offer the same level of thread safety as | |
707 | built-in types. A <code>shared_ptr</code> instance can be "read" (accessed | |
708 | using only const operations) simultaneously by multiple threads. Different <code>shared_ptr</code> | |
709 | instances can be "written to" (accessed using mutable operations such as <code>operator= | |
710 | </code>or <code>reset</code>) simultaneously by multiple threads (even | |
711 | when these instances are copies, and share the same reference count | |
712 | underneath.)</p> | |
713 | <p>Any other simultaneous accesses result in undefined behavior.</p> | |
714 | <p>Examples:</p> | |
715 | <pre>shared_ptr<int> p(new int(42)); | |
716 | ||
717 | //--- Example 1 --- | |
718 | ||
719 | // thread A | |
720 | shared_ptr<int> p2(p); // reads p | |
721 | ||
722 | // thread B | |
723 | shared_ptr<int> p3(p); // OK, multiple reads are safe | |
724 | ||
725 | //--- Example 2 --- | |
726 | ||
727 | // thread A | |
728 | p.reset(new int(1912)); // writes p | |
729 | ||
730 | // thread B | |
731 | p2.reset(); // OK, writes p2 | |
732 | ||
733 | //--- Example 3 --- | |
734 | ||
735 | // thread A | |
736 | p = p3; // reads p3, writes p | |
737 | ||
738 | // thread B | |
739 | p3.reset(); // writes p3; undefined, simultaneous read/write | |
740 | ||
741 | //--- Example 4 --- | |
742 | ||
743 | // thread A | |
744 | p3 = p2; // reads p2, writes p3 | |
745 | ||
746 | // thread B | |
747 | // p2 goes out of scope: undefined, the destructor is considered a "write access" | |
748 | ||
749 | //--- Example 5 --- | |
750 | ||
751 | // thread A | |
752 | p3.reset(new int(1)); | |
753 | ||
754 | // thread B | |
755 | p3.reset(new int(2)); // undefined, multiple writes | |
756 | </pre> | |
757 | <p> </p> | |
758 | <p>Starting with Boost release 1.33.0, <code>shared_ptr</code> uses a lock-free | |
759 | implementation on most common platforms.</p> | |
760 | <p>If your program is single-threaded and does not link to any libraries that might | |
761 | have used <code>shared_ptr</code> in its default configuration, you can <code> | |
762 | #define</code> the macro <code>BOOST_SP_DISABLE_THREADS</code> on a | |
763 | project-wide basis to switch to ordinary non-atomic reference count updates.</p> | |
764 | <p>(Defining <code>BOOST_SP_DISABLE_THREADS</code> in some, but not all, | |
765 | translation units is technically a violation of the One Definition Rule and | |
766 | undefined behavior. Nevertheless, the implementation attempts to do its best to | |
767 | accommodate the request to use non-atomic updates in those translation units. | |
768 | No guarantees, though.)</p> | |
769 | <p>You can define the macro <code>BOOST_SP_USE_PTHREADS</code> to turn off the | |
770 | lock-free platform-specific implementation and fall back to the generic | |
771 | <code>pthread_mutex_t</code>-based code.</p> | |
772 | <h2 id="FAQ">Frequently Asked Questions</h2> | |
773 | <p><b>Q.</b> There are several variations of shared pointers, with different | |
774 | tradeoffs; why does the smart pointer library supply only a single | |
775 | implementation? It would be useful to be able to experiment with each type so | |
776 | as to find the most suitable for the job at hand?</p> | |
777 | <p> | |
778 | <b>A.</b> An important goal of <code>shared_ptr</code> is to provide a | |
779 | standard shared-ownership pointer. Having a single pointer type is important | |
780 | for stable library interfaces, since different shared pointers typically cannot | |
781 | interoperate, i.e. a reference counted pointer (used by library A) cannot share | |
782 | ownership with a linked pointer (used by library B.) | |
783 | </p> | |
784 | <p><b>Q.</b> Why doesn't <code>shared_ptr</code> have template parameters supplying | |
785 | traits or policies to allow extensive user customization?</p> | |
786 | <p> | |
787 | <b>A.</b> Parameterization discourages users. The <code>shared_ptr</code> template is | |
788 | carefully crafted to meet common needs without extensive parameterization. Some | |
789 | day a highly configurable smart pointer may be invented that is also very easy | |
790 | to use and very hard to misuse. Until then, <code>shared_ptr</code> is the smart | |
791 | pointer of choice for a wide range of applications. (Those interested in policy | |
792 | based smart pointers should read <a href="http://www.awprofessional.com/bookstore/product.asp?isbn=0201704315&rl=1"> | |
793 | Modern C++ Design</a> by Andrei Alexandrescu.) | |
794 | </p> | |
795 | <p><b>Q.</b> I am not convinced. Default parameters can be used where appropriate | |
796 | to hide the complexity. Again, why not policies?</p> | |
797 | <p> | |
798 | <b>A.</b> Template parameters affect the type. See the answer to the first | |
799 | question above. | |
800 | </p> | |
801 | <p><b>Q.</b> Why doesn't <code>shared_ptr</code> use a linked list implementation?</p> | |
802 | <p> | |
803 | <b>A.</b> A linked list implementation does not offer enough advantages to | |
804 | offset the added cost of an extra pointer. See <a href="smarttests.htm">timings</a> | |
805 | page. In addition, it is expensive to make a linked list implementation thread | |
806 | safe. | |
807 | </p> | |
808 | <p><b>Q.</b> Why doesn't <code>shared_ptr</code> (or any of the other Boost smart | |
809 | pointers) supply an automatic conversion to <code>T*</code>?</p> | |
810 | <p> | |
811 | <b>A.</b> Automatic conversion is believed to be too error prone. | |
812 | </p> | |
813 | <p><b>Q.</b> Why does <code>shared_ptr</code> supply <code>use_count()</code>?</p> | |
814 | <p> | |
815 | <b>A.</b> As an aid to writing test cases and debugging displays. One of the | |
816 | progenitors had <code>use_count()</code>, and it was useful in tracking down bugs in a | |
817 | complex project that turned out to have cyclic-dependencies. | |
818 | </p> | |
819 | <p><b>Q.</b> Why doesn't <code>shared_ptr</code> specify complexity requirements?</p> | |
820 | <p> | |
821 | <b>A.</b> Because complexity requirements limit implementors and complicate the | |
822 | specification without apparent benefit to <code>shared_ptr</code> users. For example, | |
823 | error-checking implementations might become non-conforming if they had to meet | |
824 | stringent complexity requirements. | |
825 | </p> | |
826 | <p><b>Q.</b> Why doesn't <code>shared_ptr</code> provide a <code>release()</code> function?</p> | |
827 | <p> | |
828 | <b>A.</b> <code>shared_ptr</code> cannot give away ownership unless it's <code>unique()</code> | |
829 | because the other copy will still destroy the object.</p> | |
830 | <p>Consider:</p> | |
831 | <blockquote><pre>shared_ptr<int> a(new int); | |
832 | shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2 | |
833 | ||
834 | int * p = a.release(); | |
835 | ||
836 | // Who owns p now? b will still call delete on it in its destructor.</pre> | |
837 | </blockquote> | |
838 | <p>Furthermore, the pointer returned by <code>release()</code> would be difficult | |
839 | to deallocate reliably, as the source <code>shared_ptr</code> could have been created | |
840 | with a custom deleter. | |
841 | </p> | |
842 | <p><b>Q.</b> Why is <code>operator->()</code> const, but its return value is a | |
843 | non-const pointer to the element type?</p> | |
844 | <p> | |
845 | <b>A.</b> Shallow copy pointers, including raw pointers, typically don't | |
846 | propagate constness. It makes little sense for them to do so, as you can always | |
847 | obtain a non-const pointer from a const one and then proceed to modify the | |
848 | object through it. <code>shared_ptr</code> is "as close to raw pointers as possible | |
849 | but no closer". | |
850 | </p> | |
851 | <hr> | |
852 | <p>$Date$</p> | |
853 | <p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. | |
854 | Copyright 2002-2005, 2012, 2013 Peter Dimov. Distributed under the Boost Software License, | |
855 | Version 1.0. See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> | |
856 | or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>.</small></p> | |
857 | </body> | |
858 | </html> |