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"> |
---|
8 | <h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle" |
---|
9 | border="0"></A>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="#Handle/Body">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><a name="Introduction">Introduction</a></h2> |
---|
22 | <p>The <b>shared_ptr</b> 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 <b>shared_ptr</b> pointing to it is |
---|
25 | destroyed or reset. See the <A href="#example">example</A>.</p> |
---|
26 | <p>Every <b>shared_ptr</b> meets the <b>CopyConstructible</b> and <b>Assignable</b> |
---|
27 | requirements of the C++ Standard Library, and so can be used in standard |
---|
28 | library containers. Comparison operators are supplied so that <b>shared_ptr</b> |
---|
29 | works with the standard library's associative containers.</p> |
---|
30 | <p>Normally, a <b>shared_ptr</b> cannot correctly hold a pointer to a dynamically |
---|
31 | allocated array. See <A href="shared_array.htm"><b>shared_array</b></A> for |
---|
32 | that usage.</p> |
---|
33 | <p>Because the implementation uses reference counting, cycles of <b>shared_ptr</b> instances |
---|
34 | will not be reclaimed. For example, if <b>main()</b> holds a <b>shared_ptr</b> to |
---|
35 | <b>A</b>, which directly or indirectly holds a <b>shared_ptr</b> back to <b>A</b>, |
---|
36 | <b>A</b>'s use count will be 2. Destruction of the original <b>shared_ptr</b> will |
---|
37 | leave <b>A</b> dangling with a use count of 1. Use <A href="weak_ptr.htm">weak_ptr</A> |
---|
38 | to "break cycles."</p> |
---|
39 | <p>The class template is parameterized on <b>T</b>, the type of the object pointed |
---|
40 | to. <STRONG>shared_ptr</STRONG> and most of its member functions place no |
---|
41 | requirements on <STRONG>T</STRONG>; it is allowed to be an incomplete type, or <STRONG> |
---|
42 | void</STRONG>. Member functions that do place additional requirements (<A href="#constructors">constructors</A>, |
---|
43 | <A href="#reset">reset</A>) are explicitly documented below.</p> |
---|
44 | <P><STRONG>shared_ptr<T></STRONG> can be implicitly converted to <STRONG>shared_ptr<U></STRONG> |
---|
45 | whenever <STRONG>T*</STRONG> can be implicitly converted to <STRONG>U*</STRONG>. |
---|
46 | In particular, <STRONG>shared_ptr<T></STRONG> is implicitly convertible |
---|
47 | to <STRONG>shared_ptr<T const></STRONG>, to <STRONG>shared_ptr<U></STRONG> |
---|
48 | where <STRONG>U</STRONG> is an accessible base of <STRONG>T</STRONG>, and to <STRONG> |
---|
49 | shared_ptr<void></STRONG>.</P> |
---|
50 | <P><STRONG>shared_ptr</STRONG> is now part of <STRONG>TR1</STRONG>, the first C++ |
---|
51 | Library Technical Report. The latest draft of <STRONG>TR1</STRONG> is available |
---|
52 | at the following location:</P> |
---|
53 | <P><A href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1745.pdf">http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1745.pdf</A> |
---|
54 | (1.36Mb PDF)</P> |
---|
55 | <P>This implementation conforms to the TR1 specification, with the only exception |
---|
56 | that it resides in namespace <code>boost</code> instead of <code>std::tr1</code>.</P> |
---|
57 | <h2><a name="BestPractices">Best Practices</a></h2> |
---|
58 | <P>A simple guideline that nearly eliminates the possibility of memory leaks is: |
---|
59 | always use a named smart pointer variable to hold the result of <STRONG>new. </STRONG> |
---|
60 | Every occurence of the <STRONG>new</STRONG> keyword in the code should have the |
---|
61 | form:</P> |
---|
62 | <PRE>shared_ptr<T> p(new Y);</PRE> |
---|
63 | <P>It is, of course, acceptable to use another smart pointer in place of <STRONG>shared_ptr</STRONG> |
---|
64 | above; having <STRONG>T</STRONG> and <STRONG>Y</STRONG> be the same type, or |
---|
65 | passing arguments to <STRONG>Y</STRONG>'s constructor is also OK.</P> |
---|
66 | <P>If you observe this guideline, it naturally follows that you will have no |
---|
67 | explicit <STRONG>delete</STRONG>s; <STRONG>try/catch</STRONG> constructs will |
---|
68 | be rare.</P> |
---|
69 | <P>Avoid using unnamed <STRONG>shared_ptr</STRONG> temporaries to save typing; to |
---|
70 | see why this is dangerous, consider this example:</P> |
---|
71 | <PRE>void f(shared_ptr<int>, int); |
---|
72 | int g(); |
---|
73 | |
---|
74 | void ok() |
---|
75 | { |
---|
76 | shared_ptr<int> p(new int(2)); |
---|
77 | f(p, g()); |
---|
78 | } |
---|
79 | |
---|
80 | void bad() |
---|
81 | { |
---|
82 | f(shared_ptr<int>(new int(2)), g()); |
---|
83 | } |
---|
84 | </PRE> |
---|
85 | <P>The function <STRONG>ok</STRONG> follows the guideline to the letter, whereas <STRONG> |
---|
86 | bad</STRONG> constructs the temporary <STRONG>shared_ptr</STRONG> in place, |
---|
87 | admitting the possibility of a memory leak. Since function arguments are |
---|
88 | evaluated in unspecified order, it is possible for <STRONG>new int(2)</STRONG> to |
---|
89 | be evaluated first, <STRONG>g()</STRONG> second, and we may never get to the <STRONG> |
---|
90 | shared_ptr </STRONG>constructor if <STRONG>g</STRONG> throws an exception. |
---|
91 | 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"> |
---|
92 | here</A>) of the issue for more information.</P> |
---|
93 | <h2><a name="Synopsis">Synopsis</a></h2> |
---|
94 | <pre>namespace boost { |
---|
95 | |
---|
96 | class bad_weak_ptr: public std::exception; |
---|
97 | |
---|
98 | template<class T> class <A href="weak_ptr.htm" >weak_ptr</A>; |
---|
99 | |
---|
100 | template<class T> class shared_ptr { |
---|
101 | |
---|
102 | public: |
---|
103 | |
---|
104 | typedef T <A href="#element_type" >element_type</A>; |
---|
105 | |
---|
106 | <A href="#constructors" >shared_ptr</A>(); // never throws |
---|
107 | template<class Y> explicit <A href="#constructors" >shared_ptr</A>(Y * p); |
---|
108 | template<class Y, class D> <A href="#constructors" >shared_ptr</A>(Y * p, D d); |
---|
109 | template<class Y, class D, class A> <A href="#allocator_constructor" >shared_ptr</A>(Y * p, D d, A a); |
---|
110 | <A href="#destructor" >~shared_ptr</A>(); // never throws |
---|
111 | |
---|
112 | <A href="#constructors" >shared_ptr</A>(shared_ptr const & r); // never throws |
---|
113 | template<class Y> <A href="#constructors" >shared_ptr</A>(shared_ptr<Y> const & r); // never throws |
---|
114 | template<class Y> explicit <A href="#constructors" >shared_ptr</A>(<A href="weak_ptr.htm" >weak_ptr</A><Y> const & r); |
---|
115 | template<class Y> explicit <A href="#constructors" >shared_ptr</A>(std::auto_ptr<Y> & r); |
---|
116 | |
---|
117 | shared_ptr & <A href="#assignment" >operator=</A>(shared_ptr const & r); // never throws |
---|
118 | template<class Y> shared_ptr & <A href="#assignment" >operator=</A>(shared_ptr<Y> const & r); // never throws |
---|
119 | template<class Y> shared_ptr & <A href="#assignment" >operator=</A>(std::auto_ptr<Y> & r); |
---|
120 | |
---|
121 | void <A href="#reset" >reset</A>(); // never throws |
---|
122 | template<class Y> void <A href="#reset" >reset</A>(Y * p); |
---|
123 | template<class Y, class D> void <A href="#reset" >reset</A>(Y * p, D d); |
---|
124 | template<class Y, class D, class A> void <A href="#reset" >reset</A>(Y * p, D d, A a); |
---|
125 | |
---|
126 | T & <A href="#indirection" >operator*</A>() const; // never throws |
---|
127 | T * <A href="#indirection" >operator-></A>() const; // never throws |
---|
128 | T * <A href="#get" >get</A>() const; // never throws |
---|
129 | |
---|
130 | bool <A href="#unique" >unique</A>() const; // never throws |
---|
131 | long <A href="#use_count" >use_count</A>() const; // never throws |
---|
132 | |
---|
133 | operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws |
---|
134 | |
---|
135 | void <A href="#swap" >swap</A>(shared_ptr & b); // never throws |
---|
136 | }; |
---|
137 | |
---|
138 | template<class T, class U> |
---|
139 | bool <A href="#comparison" >operator==</A>(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws |
---|
140 | |
---|
141 | template<class T, class U> |
---|
142 | bool <A href="#comparison" >operator!=</A>(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws |
---|
143 | |
---|
144 | template<class T, class U> |
---|
145 | bool <A href="#comparison" >operator<</A>(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws |
---|
146 | |
---|
147 | template<class T> void <A href="#free-swap" >swap</A>(shared_ptr<T> & a, shared_ptr<T> & b); // never throws |
---|
148 | |
---|
149 | template<class T> T * <A href="#get_pointer" >get_pointer</A>(shared_ptr<T> const & p); // never throws |
---|
150 | |
---|
151 | template<class T, class U> |
---|
152 | shared_ptr<T> <A href="#static_pointer_cast" >static_pointer_cast</A>(shared_ptr<U> const & r); // never throws |
---|
153 | |
---|
154 | template<class T, class U> |
---|
155 | shared_ptr<T> <A href="#const_pointer_cast" >const_pointer_cast</A>(shared_ptr<U> const & r); // never throws |
---|
156 | |
---|
157 | template<class T, class U> |
---|
158 | shared_ptr<T> <A href="#dynamic_pointer_cast" >dynamic_pointer_cast</A>(shared_ptr<U> const & r); // never throws |
---|
159 | |
---|
160 | template<class E, class T, class Y> |
---|
161 | std::basic_ostream<E, T> & <A href="#insertion-operator" >operator<<</A> (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p); |
---|
162 | |
---|
163 | template<class D, class T> |
---|
164 | D * <A href="#get_deleter">get_deleter</A>(shared_ptr<T> const & p); |
---|
165 | }</pre> |
---|
166 | <h2><a name="Members">Members</a></h2> |
---|
167 | <h3><a name="element_type">element_type</a></h3> |
---|
168 | <pre>typedef T element_type;</pre> |
---|
169 | <blockquote> |
---|
170 | <p>Provides the type of the template parameter T.</p> |
---|
171 | </blockquote> |
---|
172 | <h3><a name="constructors">constructors</a></h3> |
---|
173 | <pre>shared_ptr(); // never throws</pre> |
---|
174 | <blockquote> |
---|
175 | <p><b>Effects:</b> Constructs an <EM>empty</EM> <b>shared_ptr</b>.</p> |
---|
176 | <p><b>Postconditions:</b> <code>use_count() == 0 && get() == 0</code>.</p> |
---|
177 | <p><b>Throws:</b> nothing.</p> |
---|
178 | </blockquote> |
---|
179 | <P><EM>[The nothrow guarantee is important, since <STRONG>reset()</STRONG> is specified |
---|
180 | in terms of the default constructor; this implies that the constructor must not |
---|
181 | allocate memory.]</EM></P> |
---|
182 | <pre>template<class Y> explicit shared_ptr(Y * p);</pre> |
---|
183 | <blockquote> |
---|
184 | <p><b>Requirements:</b> <b>p</b> must be convertible to <b>T *</b>. <STRONG>Y</STRONG> |
---|
185 | must be a complete type. The expression <code>delete p</code> must be |
---|
186 | well-formed, must not invoke undefined behavior, and must not throw exceptions. |
---|
187 | </p> |
---|
188 | <p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>owns</EM> the pointer <b>p</b>.</p> |
---|
189 | <p><b>Postconditions:</b> <code>use_count() == 1 && get() == p</code>.</p> |
---|
190 | <p><b>Throws:</b> <STRONG>std::bad_alloc</STRONG>, or an implementation-defined |
---|
191 | exception when a resource other than memory could not be obtained.</p> |
---|
192 | <p><b>Exception safety:</b> If an exception is thrown, <code>delete p</code> is |
---|
193 | called.</p> |
---|
194 | <P><STRONG>Notes:</STRONG> <B>p</B> must be a pointer to an object that was |
---|
195 | allocated via a C++ <B>new</B> expression or be 0. The postcondition that <A href="#use_count"> |
---|
196 | use count</A> is 1 holds even if <b>p</b> is 0; invoking <STRONG>delete</STRONG> |
---|
197 | on a pointer that has a value of 0 is harmless.</P> |
---|
198 | </blockquote> |
---|
199 | <P><EM>[This constructor has been changed to a template in order to remember the actual |
---|
200 | pointer type passed. The destructor will call <STRONG>delete</STRONG> with the |
---|
201 | same pointer, complete with its original type, even when <STRONG>T</STRONG> does |
---|
202 | not have a virtual destructor, or is <STRONG>void</STRONG>.</EM></P> |
---|
203 | <P><EM>The optional intrusive counting support has been dropped as it exposes too much |
---|
204 | implementation details and doesn't interact well with <STRONG>weak_ptr</STRONG>. |
---|
205 | The current implementation uses a different mechanism, <A href="enable_shared_from_this.html"> |
---|
206 | enable_shared_from_this</A>, to solve the "<STRONG>shared_ptr</STRONG> from <STRONG> |
---|
207 | this</STRONG>" problem.</EM><EM>]</EM></P> |
---|
208 | <a name="allocator_constructor"></a> |
---|
209 | <pre>template<class Y, class D> shared_ptr(Y * p, D d); |
---|
210 | template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);</pre> |
---|
211 | <blockquote> |
---|
212 | <p><b>Requirements:</b> <B>p</B> must be convertible to <B>T *</B>. <STRONG>D</STRONG> |
---|
213 | must be <STRONG>CopyConstructible</STRONG>. The copy constructor and destructor |
---|
214 | of <b>D</b> must not throw. The expression <code>d(p)</code> must be |
---|
215 | well-formed, must not invoke undefined behavior, and must not throw exceptions. <STRONG> |
---|
216 | A</STRONG> must be an <EM>Allocator</EM>, as described in section 20.1.5 (<STRONG>Allocator |
---|
217 | requirements</STRONG>) of the C++ Standard. |
---|
218 | </p> |
---|
219 | <p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>owns</EM> the pointer <STRONG> |
---|
220 | p</STRONG> and the deleter <b>d</b>. The second constructor allocates |
---|
221 | memory using a copy of <STRONG>a</STRONG>.</p> |
---|
222 | <p><b>Postconditions:</b> <code>use_count() == 1 && get() == p</code>.</p> |
---|
223 | <p><b>Throws:</b> <STRONG>std::bad_alloc</STRONG>, or an implementation-defined |
---|
224 | exception when a resource other than memory could not be obtained.</p> |
---|
225 | <p><b>Exception safety:</b> If an exception is thrown, <code>d(p)</code> is called.</p> |
---|
226 | <p><b>Notes:</b> When the the time comes to delete the object pointed to by <b>p</b>, |
---|
227 | the stored copy of <STRONG>d</STRONG> is invoked with the stored copy of <STRONG>p</STRONG> |
---|
228 | as an argument.</p> |
---|
229 | </blockquote> |
---|
230 | <P><EM>[Custom deallocators allow a factory function returning a <STRONG>shared_ptr</STRONG> |
---|
231 | to insulate the user from its memory allocation strategy. Since the deallocator |
---|
232 | is not part of the type, changing the allocation strategy does not break source |
---|
233 | or binary compatibility, and does not require a client recompilation. For |
---|
234 | example, a "no-op" deallocator is useful when returning a <STRONG>shared_ptr</STRONG> |
---|
235 | to a statically allocated object, and other variations allow a <STRONG>shared_ptr</STRONG> |
---|
236 | to be used as a wrapper for another smart pointer, easing interoperability.</EM></P> |
---|
237 | <P><EM>The support for custom deallocators does not impose significant overhead. Other <STRONG> |
---|
238 | shared_ptr</STRONG> features still require a deallocator to be kept.</EM></P> |
---|
239 | <P><EM>The requirement that the copy constructor of <b>D</b> does not throw comes from |
---|
240 | the pass by value. If the copy constructor throws, the pointer is leaked. |
---|
241 | Removing the requirement requires a pass by (const) reference.</EM></P> |
---|
242 | <P><EM>The main problem with pass by reference lies in its interaction with rvalues. A |
---|
243 | const reference may still cause a copy, and will require a const operator(). A |
---|
244 | non-const reference won't bind to an rvalue at all. A good solution to this |
---|
245 | problem is the rvalue reference proposed in <A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1377.htm"> |
---|
246 | N1377</A>/<A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm">N1385</A>.]</EM></P> |
---|
247 | <pre>shared_ptr(shared_ptr const & r); // never throws |
---|
248 | template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws</pre> |
---|
249 | <blockquote> |
---|
250 | <p><b>Effects:</b> If <b>r</b> is <EM>empty</EM>, constructs an <EM>empty</EM> <b>shared_ptr</b>; |
---|
251 | otherwise, constructs a <b>shared_ptr</b> that <EM>shares ownership</EM> with <b>r</b>.</p> |
---|
252 | <p><b>Postconditions:</b> <code>get() == r.get() && use_count() == |
---|
253 | r.use_count()</code>.</p> |
---|
254 | <p><b>Throws:</b> nothing.</p> |
---|
255 | </blockquote> |
---|
256 | <pre>template<class Y> explicit shared_ptr(<A href="weak_ptr.htm" >weak_ptr</A><Y> const & r);</pre> |
---|
257 | <blockquote> |
---|
258 | <p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>shares ownership</EM> with |
---|
259 | <b>r</b> and stores a copy of the pointer stored in <STRONG>r</STRONG>.</p> |
---|
260 | <p><b>Postconditions:</b> <code>use_count() == r.use_count()</code>.</p> |
---|
261 | <p><b>Throws:</b> <b>bad_weak_ptr</b> when <code>r.use_count() == 0</code>.</p> |
---|
262 | <p><b>Exception safety:</b> If an exception is thrown, the constructor has no |
---|
263 | effect.</p> |
---|
264 | </blockquote> |
---|
265 | <pre>template<class Y> shared_ptr(std::auto_ptr<Y> & r);</pre> |
---|
266 | <BLOCKQUOTE> |
---|
267 | <P><B>Effects:</B> Constructs a <B>shared_ptr</B>, as if by storing a copy of <STRONG>r.release()</STRONG>.</P> |
---|
268 | <p><b>Postconditions:</b> <code>use_count() == 1</code>.</p> |
---|
269 | <p><b>Throws:</b> <STRONG>std::bad_alloc</STRONG>, or an implementation-defined |
---|
270 | exception when a resource other than memory could not be obtained.</p> |
---|
271 | <P><B>Exception safety:</B> If an exception is thrown, the constructor has no |
---|
272 | effect.</P> |
---|
273 | </BLOCKQUOTE> |
---|
274 | <P><EM>[This constructor takes a the source <STRONG>auto_ptr</STRONG> by reference and |
---|
275 | not by value, and cannot accept <STRONG>auto_ptr</STRONG> temporaries. This is |
---|
276 | by design, as the constructor offers the strong guarantee; an rvalue reference |
---|
277 | would solve this problem, too.]</EM></P> |
---|
278 | <h3><a name="destructor">destructor</a></h3> |
---|
279 | <pre>~shared_ptr(); // never throws</pre> |
---|
280 | <BLOCKQUOTE> |
---|
281 | <P><B>Effects:</B></P> |
---|
282 | <UL> |
---|
283 | <LI> |
---|
284 | If <STRONG>*this</STRONG> is <EM>empty</EM>, or <EM>shares ownership</EM> with |
---|
285 | another <STRONG>shared_ptr</STRONG> instance (<code>use_count() > 1</code>), |
---|
286 | there are no side effects. |
---|
287 | <LI> |
---|
288 | Otherwise, if <STRONG>*this</STRONG> <EM>owns</EM> a pointer <STRONG>p</STRONG> |
---|
289 | and a deleter <STRONG>d</STRONG>, <code>d(p)</code> |
---|
290 | is called. |
---|
291 | <LI> |
---|
292 | Otherwise, <STRONG>*this</STRONG> <EM>owns</EM> a pointer <STRONG>p</STRONG>, |
---|
293 | and <code>delete p</code> is called.</LI></UL> |
---|
294 | <P><B>Throws:</B> nothing.</P> |
---|
295 | </BLOCKQUOTE> |
---|
296 | <H3><a name="assignment">assignment</a></H3> |
---|
297 | <pre>shared_ptr & operator=(shared_ptr const & r); // never throws |
---|
298 | template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r); // never throws |
---|
299 | template<class Y> shared_ptr & operator=(std::auto_ptr<Y> & r);</pre> |
---|
300 | <BLOCKQUOTE> |
---|
301 | <P><B>Effects:</B> Equivalent to <code>shared_ptr(r).swap(*this)</code>.</P> |
---|
302 | <P><B>Returns:</B> <code>*this</code>.</P> |
---|
303 | <P><B>Notes:</B> The use count updates caused by the temporary object construction |
---|
304 | and destruction are not considered observable side effects, and the |
---|
305 | implementation is free to meet the effects (and the implied guarantees) via |
---|
306 | different means, without creating a temporary. In particular, in the example:</P> |
---|
307 | <pre>shared_ptr<int> p(new int); |
---|
308 | shared_ptr<void> q(p); |
---|
309 | p = p; |
---|
310 | q = p; |
---|
311 | </pre> |
---|
312 | <p>both assignments may be no-ops.</p> |
---|
313 | </BLOCKQUOTE> |
---|
314 | <h3><a name="reset">reset</a></h3> |
---|
315 | <pre>void reset(); // never throws</pre> |
---|
316 | <BLOCKQUOTE> |
---|
317 | <P><B>Effects:</B> Equivalent to <code>shared_ptr().swap(*this)</code>.</P> |
---|
318 | </BLOCKQUOTE> |
---|
319 | <pre>template<class Y> void reset(Y * p);</pre> |
---|
320 | <BLOCKQUOTE> |
---|
321 | <P><B>Effects:</B> Equivalent to <code>shared_ptr(p).swap(*this)</code>.</P> |
---|
322 | </BLOCKQUOTE> |
---|
323 | <pre>template<class Y, class D> void reset(Y * p, D d);</pre> |
---|
324 | <BLOCKQUOTE> |
---|
325 | <P><B>Effects:</B> Equivalent to <code>shared_ptr(p, d).swap(*this)</code>.</P> |
---|
326 | </BLOCKQUOTE> |
---|
327 | <pre>template<class Y, class D, class A> void reset(Y * p, D d, A a);</pre> |
---|
328 | <BLOCKQUOTE> |
---|
329 | <P><B>Effects:</B> Equivalent to <code>shared_ptr(p, d, a).swap(*this)</code>.</P> |
---|
330 | </BLOCKQUOTE> |
---|
331 | <h3><a name="indirection">indirection</a></h3> |
---|
332 | <pre>T & operator*() const; // never throws</pre> |
---|
333 | <blockquote> |
---|
334 | <p><b>Requirements:</b> The stored pointer must not be 0.</p> |
---|
335 | <p><b>Returns:</b> a reference to the object pointed to by the stored pointer.</p> |
---|
336 | <p><b>Throws:</b> nothing.</p> |
---|
337 | </blockquote> |
---|
338 | <pre>T * operator->() const; // never throws</pre> |
---|
339 | <blockquote> |
---|
340 | <p><b>Requirements:</b> The stored pointer must not be 0.</p> |
---|
341 | <p><b>Returns:</b> the stored pointer.</p> |
---|
342 | <p><b>Throws:</b> nothing.</p> |
---|
343 | </blockquote> |
---|
344 | <h3><a name="get">get</a></h3> |
---|
345 | <pre>T * get() const; // never throws</pre> |
---|
346 | <blockquote> |
---|
347 | <p><b>Returns:</b> the stored pointer.</p> |
---|
348 | <p><b>Throws:</b> nothing.</p> |
---|
349 | </blockquote> |
---|
350 | <h3><a name="unique">unique</a></h3> |
---|
351 | <pre>bool unique() const; // never throws</pre> |
---|
352 | <blockquote> |
---|
353 | <p><b>Returns:</b> <code>use_count() == 1</code>.</p> |
---|
354 | <p><b>Throws:</b> nothing.</p> |
---|
355 | <P><B>Notes:</B> <code>unique()</code> may be faster than <code>use_count()</code>. |
---|
356 | If you are using <code>unique()</code> to implement copy on write, do not rely |
---|
357 | on a specific value when the stored pointer is zero.</P> |
---|
358 | </blockquote> |
---|
359 | <h3><a name="use_count">use_count</a></h3> |
---|
360 | <pre>long use_count() const; // never throws</pre> |
---|
361 | <blockquote> |
---|
362 | <p><b>Returns:</b> the number of <b>shared_ptr</b> objects, <STRONG>*this</STRONG> included, |
---|
363 | that <i>share ownership</i> with <b>*this</b>, or an unspecified nonnegative |
---|
364 | value when <STRONG>*this</STRONG> is <EM>empty</EM>.</p> |
---|
365 | <p><b>Throws:</b> nothing.</p> |
---|
366 | <P><B>Notes:</B> <code>use_count()</code> is not necessarily efficient. Use only |
---|
367 | for debugging and testing purposes, not for production code.</P> |
---|
368 | </blockquote> |
---|
369 | <h3><a name="conversions">conversions</a></h3> |
---|
370 | <pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre> |
---|
371 | <blockquote> |
---|
372 | <p><b>Returns:</b> an unspecified value that, when used in boolean contexts, is |
---|
373 | equivalent to <code>get() != 0</code>.</p> |
---|
374 | <p><b>Throws:</b> nothing.</p> |
---|
375 | <P><B>Notes:</B> This conversion operator allows <b>shared_ptr</b> objects to be |
---|
376 | used in boolean contexts, like <code>if (p && p->valid()) {}</code>. |
---|
377 | The actual target type is typically a pointer to a member function, avoiding |
---|
378 | many of the implicit conversion pitfalls.</P> |
---|
379 | </blockquote> |
---|
380 | <P><EM>[The conversion to bool is not merely syntactic sugar. It allows <STRONG>shared_ptr</STRONG>s |
---|
381 | to be declared in conditions when using <A href="#dynamic_pointer_cast">dynamic_pointer_cast</A> |
---|
382 | or <A href="weak_ptr.htm#lock">weak_ptr::lock</A>.]</EM></P> |
---|
383 | <h3><a name="swap">swap</a></h3> |
---|
384 | <pre>void swap(shared_ptr & b); // never throws</pre> |
---|
385 | <blockquote> |
---|
386 | <p><b>Effects:</b> Exchanges the contents of the two smart pointers.</p> |
---|
387 | <p><b>Throws:</b> nothing.</p> |
---|
388 | </blockquote> |
---|
389 | <h2><a name="functions">Free Functions</a></h2> |
---|
390 | <h3><a name="comparison">comparison</a></h3> |
---|
391 | <pre>template<class T, class U> |
---|
392 | bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws</pre> |
---|
393 | <blockquote> |
---|
394 | <p><b>Returns:</b> <code>a.get() == b.get()</code>.</p> |
---|
395 | <p><b>Throws:</b> nothing.</p> |
---|
396 | </blockquote> |
---|
397 | <pre>template<class T, class U> |
---|
398 | bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws</pre> |
---|
399 | <blockquote> |
---|
400 | <p><b>Returns:</b> <code>a.get() != b.get()</code>.</p> |
---|
401 | <p><b>Throws:</b> nothing.</p> |
---|
402 | </blockquote> |
---|
403 | <pre>template<class T, class U> |
---|
404 | bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws</pre> |
---|
405 | <blockquote> |
---|
406 | <p><b>Returns:</b> an unspecified value such that</p> |
---|
407 | <UL> |
---|
408 | <LI> |
---|
409 | <b>operator<</b> is a strict weak ordering as described in section 25.3 <code>[lib.alg.sorting]</code> |
---|
410 | of the C++ standard; |
---|
411 | <LI> |
---|
412 | under the equivalence relation defined by <STRONG>operator<</STRONG>, <code>!(a |
---|
413 | < b) && !(b < a)</code>, two <STRONG>shared_ptr</STRONG> instances |
---|
414 | are equivalent if and only if they <EM>share ownership</EM> or are both <EM>empty</EM>.</LI></UL> |
---|
415 | <p><b>Throws:</b> nothing.</p> |
---|
416 | <P><B>Notes:</B> Allows <STRONG>shared_ptr</STRONG> objects to be used as keys in |
---|
417 | associative containers.</P> |
---|
418 | </blockquote> |
---|
419 | <P><EM>[<STRONG>Operator<</STRONG> has been preferred over a <STRONG>std::less </STRONG> |
---|
420 | specialization for consistency and legality reasons, as <STRONG>std::less</STRONG> |
---|
421 | is required to return the results of <STRONG>operator<</STRONG>, and many |
---|
422 | standard algorithms use <STRONG>operator<</STRONG> instead of <STRONG>std::less</STRONG> |
---|
423 | for comparisons when a predicate is not supplied. Composite objects, like <STRONG>std::pair</STRONG>, |
---|
424 | also implement their <STRONG>operator<</STRONG> in terms of their contained |
---|
425 | subobjects' <STRONG>operator<</STRONG>.</EM></P> |
---|
426 | <P><EM>The rest of the comparison operators are omitted by design.]</EM></P> |
---|
427 | <h3><a name="free-swap">swap</a></h3> |
---|
428 | <pre>template<class T> |
---|
429 | void swap(shared_ptr<T> & a, shared_ptr<T> & b); // never throws</pre> |
---|
430 | <BLOCKQUOTE> |
---|
431 | <P><B>Effects:</B> Equivalent to <code>a.swap(b)</code>.</P> |
---|
432 | <P><B>Throws:</B> nothing.</P> |
---|
433 | <P><B>Notes:</B> Matches the interface of <B>std::swap</B>. Provided as an aid to |
---|
434 | generic programming.</P> |
---|
435 | </BLOCKQUOTE> |
---|
436 | <P><EM>[<STRONG>swap</STRONG> is defined in the same namespace as <STRONG>shared_ptr</STRONG> |
---|
437 | as this is currently the only legal way to supply a <STRONG>swap</STRONG> function |
---|
438 | that has a chance to be used by the standard library.]</EM></P> |
---|
439 | <h3><a name="get_pointer">get_pointer</a></h3> |
---|
440 | <pre>template<class T> |
---|
441 | T * get_pointer(shared_ptr<T> const & p); // never throws</pre> |
---|
442 | <BLOCKQUOTE> |
---|
443 | <P><B>Returns:</B> <code>p.get()</code>.</P> |
---|
444 | <P><B>Throws:</B> nothing.</P> |
---|
445 | <P><B>Notes:</B> Provided as an aid to generic programming. Used by <A href="../bind/mem_fn.html"> |
---|
446 | mem_fn</A>.</P> |
---|
447 | </BLOCKQUOTE> |
---|
448 | <h3><a name="static_pointer_cast">static_pointer_cast</a></h3> |
---|
449 | <pre>template<class T, class U> |
---|
450 | shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r); // never throws</pre> |
---|
451 | <BLOCKQUOTE> |
---|
452 | <P><STRONG>Requires:</STRONG> The expression <code>static_cast<T*>(r.get())</code> |
---|
453 | must be well-formed.</P> |
---|
454 | <P><B>Returns:</B> If <b>r</b> is <i>empty</i>, an <i>empty</i> <b>shared_ptr<T></b>; |
---|
455 | otherwise, a <STRONG>shared_ptr<T></STRONG> object that stores a copy of <code> |
---|
456 | static_cast<T*>(r.get())</code> and <i>shares ownership</i> with <b>r</b>.</P> |
---|
457 | <P><B>Throws:</B> nothing.</P> |
---|
458 | <P><B>Notes:</B> the seemingly equivalent expression</P> |
---|
459 | <p><code>shared_ptr<T>(static_cast<T*>(r.get()))</code></p> |
---|
460 | <p>will eventually result in undefined behavior, attempting to delete the same |
---|
461 | object twice.</p> |
---|
462 | </BLOCKQUOTE> |
---|
463 | <h3><a name="const_pointer_cast">const_pointer_cast</a></h3> |
---|
464 | <pre>template<class T, class U> |
---|
465 | shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r); // never throws</pre> |
---|
466 | <BLOCKQUOTE> |
---|
467 | <P><STRONG>Requires:</STRONG> The expression <code>const_cast<T*>(r.get())</code> |
---|
468 | must be well-formed.</P> |
---|
469 | <P><B>Returns:</B> If <b>r</b> is <i>empty</i>, an <i>empty</i> <b>shared_ptr<T></b>; |
---|
470 | otherwise, a <STRONG>shared_ptr<T></STRONG> object that stores a copy of <code> |
---|
471 | const_cast<T*>(r.get())</code> and <i>shares ownership</i> with <b>r</b>.</P> |
---|
472 | <P><B>Throws:</B> nothing.</P> |
---|
473 | <P><B>Notes:</B> the seemingly equivalent expression</P> |
---|
474 | <p><code>shared_ptr<T>(const_cast<T*>(r.get()))</code></p> |
---|
475 | <p>will eventually result in undefined behavior, attempting to delete the same |
---|
476 | object twice.</p> |
---|
477 | </BLOCKQUOTE> |
---|
478 | <h3><a name="dynamic_pointer_cast">dynamic_pointer_cast</a></h3> |
---|
479 | <pre>template<class T, class U> |
---|
480 | shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r);</pre> |
---|
481 | <BLOCKQUOTE> |
---|
482 | <P><STRONG>Requires:</STRONG> The expression <CODE>dynamic_cast<T*>(r.get())</CODE> |
---|
483 | must be well-formed and its behavior defined.</P> |
---|
484 | <P><B>Returns:</B></P> |
---|
485 | <UL> |
---|
486 | <LI> |
---|
487 | When <CODE>dynamic_cast<T*>(r.get())</CODE> returns a nonzero value, a <STRONG> |
---|
488 | shared_ptr<T></STRONG> object that stores a copy of it and <i>shares |
---|
489 | ownership</i> with <STRONG>r</STRONG>; |
---|
490 | <LI> |
---|
491 | Otherwise, an <i>empty</i> <STRONG>shared_ptr<T></STRONG> object.</LI></UL> |
---|
492 | <P><B>Throws:</B> nothing.</P> |
---|
493 | <P><B>Notes:</B> the seemingly equivalent expression</P> |
---|
494 | <P><CODE>shared_ptr<T>(dynamic_cast<T*>(r.get()))</CODE></P> |
---|
495 | <P>will eventually result in undefined behavior, attempting to delete the same |
---|
496 | object twice.</P> |
---|
497 | </BLOCKQUOTE> |
---|
498 | <h3><a name="insertion-operator">operator<<</a></h3> |
---|
499 | <pre>template<class E, class T, class Y> |
---|
500 | std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p);</pre> |
---|
501 | <BLOCKQUOTE> |
---|
502 | <p><STRONG>Effects:</STRONG> <code>os << p.get();</code>.</p> |
---|
503 | <P><B>Returns:</B> <b>os</b>.</P> |
---|
504 | </BLOCKQUOTE> |
---|
505 | <h3><a name="get_deleter">get_deleter</a></h3> |
---|
506 | <pre>template<class D, class T> |
---|
507 | D * get_deleter(shared_ptr<T> const & p);</pre> |
---|
508 | <BLOCKQUOTE> |
---|
509 | <P><B>Returns:</B> If <STRONG>*this</STRONG> <EM>owns</EM> a deleter <STRONG>d</STRONG> |
---|
510 | of type (cv-unqualified) <STRONG>D</STRONG>, returns <code>&d</code>; |
---|
511 | otherwise returns 0.</P> |
---|
512 | </BLOCKQUOTE> |
---|
513 | <h2><a name="example">Example</a></h2> |
---|
514 | <p>See <A href="example/shared_ptr_example.cpp">shared_ptr_example.cpp</A> for a |
---|
515 | complete example program. The program builds a <b>std::vector</b> and <b>std::set</b> |
---|
516 | of <b>shared_ptr</b> objects.</p> |
---|
517 | <p>Note that after the containers have been populated, some of the <b>shared_ptr</b> |
---|
518 | objects will have a use count of 1 rather than a use count of 2, since the set |
---|
519 | is a <b>std::set</b> rather than a <b>std::multiset</b>, and thus does not |
---|
520 | contain duplicate entries. Furthermore, the use count may be even higher at |
---|
521 | various times while <b>push_back</b> and <b>insert</b> container operations are |
---|
522 | performed. More complicated yet, the container operations may throw exceptions |
---|
523 | under a variety of circumstances. Getting the memory management and exception |
---|
524 | handling in this example right without a smart pointer would be a nightmare.</p> |
---|
525 | <h2><a name="Handle/Body">Handle/Body</a> Idiom</h2> |
---|
526 | <p>One common usage of <b>shared_ptr</b> is to implement a handle/body (also called |
---|
527 | pimpl) idiom which avoids exposing the body (implementation) in the header |
---|
528 | file.</p> |
---|
529 | <p>The <A href="example/shared_ptr_example2_test.cpp">shared_ptr_example2_test.cpp</A> |
---|
530 | sample program includes a header file, <A href="example/shared_ptr_example2.hpp">shared_ptr_example2.hpp</A>, |
---|
531 | which uses a <b>shared_ptr<></b> to an incomplete type to hide the |
---|
532 | implementation. The instantiation of member functions which require a complete |
---|
533 | type occurs in the <A href="example/shared_ptr_example2.cpp">shared_ptr_example2.cpp</A> |
---|
534 | implementation file. Note that there is no need for an explicit destructor. |
---|
535 | Unlike ~scoped_ptr, ~shared_ptr does not require that <b>T</b> be a complete |
---|
536 | type.</p> |
---|
537 | <h2><a name="ThreadSafety">Thread Safety</a></h2> |
---|
538 | <p><STRONG>shared_ptr</STRONG> objects offer the same level of thread safety as |
---|
539 | built-in types. A <STRONG>shared_ptr</STRONG> instance can be "read" (accessed |
---|
540 | using only const operations) simultaneously by multiple threads. Different <STRONG>shared_ptr</STRONG> |
---|
541 | instances can be "written to" (accessed using mutable operations such as <STRONG>operator= |
---|
542 | </STRONG>or <STRONG>reset</STRONG>) simultaneosly by multiple threads (even |
---|
543 | when these instances are copies, and share the same reference count |
---|
544 | underneath.)</p> |
---|
545 | <P>Any other simultaneous accesses result in undefined behavior.</P> |
---|
546 | <P>Examples:</P> |
---|
547 | <pre>shared_ptr<int> p(new int(42)); |
---|
548 | |
---|
549 | //--- Example 1 --- |
---|
550 | |
---|
551 | // thread A |
---|
552 | shared_ptr<int> p2(p); // reads p |
---|
553 | |
---|
554 | // thread B |
---|
555 | shared_ptr<int> p3(p); // OK, multiple reads are safe |
---|
556 | |
---|
557 | //--- Example 2 --- |
---|
558 | |
---|
559 | // thread A |
---|
560 | p.reset(new int(1912)); // writes p |
---|
561 | |
---|
562 | // thread B |
---|
563 | p2.reset(); // OK, writes p2 |
---|
564 | |
---|
565 | //--- Example 3 --- |
---|
566 | |
---|
567 | // thread A |
---|
568 | p = p3; // reads p3, writes p |
---|
569 | |
---|
570 | // thread B |
---|
571 | p3.reset(); // writes p3; undefined, simultaneous read/write |
---|
572 | |
---|
573 | //--- Example 4 --- |
---|
574 | |
---|
575 | // thread A |
---|
576 | p3 = p2; // reads p2, writes p3 |
---|
577 | |
---|
578 | // thread B |
---|
579 | // p2 goes out of scope: undefined, the destructor is considered a "write access" |
---|
580 | |
---|
581 | //--- Example 5 --- |
---|
582 | |
---|
583 | // thread A |
---|
584 | p3.reset(new int(1)); |
---|
585 | |
---|
586 | // thread B |
---|
587 | p3.reset(new int(2)); // undefined, multiple writes |
---|
588 | </pre> |
---|
589 | <p> </p> |
---|
590 | <P>Starting with Boost release 1.33.0, <STRONG>shared_ptr</STRONG> uses a lock-free |
---|
591 | implementation on the following platforms:</P> |
---|
592 | <UL> |
---|
593 | <LI> |
---|
594 | GNU GCC on x86 or x86-64; |
---|
595 | <LI> |
---|
596 | GNU GCC on IA64; |
---|
597 | <LI> |
---|
598 | Metrowerks CodeWarrior on PowerPC; |
---|
599 | <LI> |
---|
600 | GNU GCC on PowerPC; |
---|
601 | <LI> |
---|
602 | Windows.</LI></UL> |
---|
603 | <P>If your program is single-threaded and does not link to any libraries that might |
---|
604 | have used <STRONG>shared_ptr</STRONG> in its default configuration, you can <STRONG> |
---|
605 | #define</STRONG> the macro <STRONG>BOOST_SP_DISABLE_THREADS</STRONG> on a |
---|
606 | project-wide basis to switch to ordinary non-atomic reference count updates.</P> |
---|
607 | <P>(Defining <STRONG>BOOST_SP_DISABLE_THREADS</STRONG> in some, but not all, |
---|
608 | translation units is technically a violation of the One Definition Rule and |
---|
609 | undefined behavior. Nevertheless, the implementation attempts to do its best to |
---|
610 | accommodate the request to use non-atomic updates in those translation units. |
---|
611 | No guarantees, though.)</P> |
---|
612 | <P>You can define the macro <STRONG>BOOST_SP_USE_PTHREADS</STRONG> to turn off the |
---|
613 | lock-free platform-specific implementation and fall back to the generic <STRONG>pthread_mutex_t</STRONG>-based |
---|
614 | code.</P> |
---|
615 | <h2><a name="FAQ">Frequently Asked Questions</a></h2> |
---|
616 | <P><B>Q.</B> There are several variations of shared pointers, with different |
---|
617 | tradeoffs; why does the smart pointer library supply only a single |
---|
618 | implementation? It would be useful to be able to experiment with each type so |
---|
619 | as to find the most suitable for the job at hand?</P> |
---|
620 | <P> |
---|
621 | <b>A.</b> An important goal of <STRONG>shared_ptr</STRONG> is to provide a |
---|
622 | standard shared-ownership pointer. Having a single pointer type is important |
---|
623 | for stable library interfaces, since different shared pointers typically cannot |
---|
624 | interoperate, i.e. a reference counted pointer (used by library A) cannot share |
---|
625 | ownership with a linked pointer (used by library B.)<BR> |
---|
626 | </P> |
---|
627 | <P><B>Q.</B> Why doesn't <B>shared_ptr</B> have template parameters supplying |
---|
628 | traits or policies to allow extensive user customization?</P> |
---|
629 | <P> |
---|
630 | <B>A.</B> Parameterization discourages users. The <B>shared_ptr</B> template is |
---|
631 | carefully crafted to meet common needs without extensive parameterization. Some |
---|
632 | day a highly configurable smart pointer may be invented that is also very easy |
---|
633 | to use and very hard to misuse. Until then, <B>shared_ptr</B> is the smart |
---|
634 | pointer of choice for a wide range of applications. (Those interested in policy |
---|
635 | based smart pointers should read <A href="http://www.awprofessional.com/bookstore/product.asp?isbn=0201704315&rl=1"> |
---|
636 | Modern C++ Design</A> by Andrei Alexandrescu.)<BR> |
---|
637 | </P> |
---|
638 | <P><B>Q.</B> I am not convinced. Default parameters can be used where appropriate |
---|
639 | to hide the complexity. Again, why not policies?</P> |
---|
640 | <P> |
---|
641 | <B>A.</B> Template parameters affect the type. See the answer to the first |
---|
642 | question above.<BR> |
---|
643 | </P> |
---|
644 | <P><B>Q.</B> Why doesn't <b>shared_ptr</b> use a linked list implementation?</P> |
---|
645 | <P> |
---|
646 | <b>A.</b> A linked list implementation does not offer enough advantages to |
---|
647 | offset the added cost of an extra pointer. See <A href="smarttests.htm">timings</A> |
---|
648 | page. In addition, it is expensive to make a linked list implementation thread |
---|
649 | safe.<BR> |
---|
650 | </P> |
---|
651 | <P><b>Q.</b> Why doesn't <b>shared_ptr</b> (or any of the other Boost smart |
---|
652 | pointers) supply an automatic conversion to <b>T*</b>?</P> |
---|
653 | <P> |
---|
654 | <b>A.</b> Automatic conversion is believed to be too error prone.<BR> |
---|
655 | </P> |
---|
656 | <P><B>Q.</B> Why does <b>shared_ptr</b> supply use_count()?</P> |
---|
657 | <P> |
---|
658 | <b>A.</b> As an aid to writing test cases and debugging displays. One of the |
---|
659 | progenitors had use_count(), and it was useful in tracking down bugs in a |
---|
660 | complex project that turned out to have cyclic-dependencies.<BR> |
---|
661 | </P> |
---|
662 | <P><B>Q.</B> Why doesn't <b>shared_ptr</b> specify complexity requirements?</P> |
---|
663 | <P> |
---|
664 | <b>A.</b> Because complexity requirements limit implementors and complicate the |
---|
665 | specification without apparent benefit to <b>shared_ptr</b> users. For example, |
---|
666 | error-checking implementations might become non-conforming if they had to meet |
---|
667 | stringent complexity requirements.<BR> |
---|
668 | </P> |
---|
669 | <P><b>Q.</b> Why doesn't <b>shared_ptr</b> provide a release() function?</P> |
---|
670 | <P> |
---|
671 | <b>A.</b> <b>shared_ptr</b> cannot give away ownership unless it's unique() |
---|
672 | because the other copy will still destroy the object.</P> |
---|
673 | <p>Consider:</p> |
---|
674 | <blockquote><pre>shared_ptr<int> a(new int); |
---|
675 | shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2 |
---|
676 | |
---|
677 | int * p = a.release(); |
---|
678 | |
---|
679 | // Who owns p now? b will still call delete on it in its destructor.</pre> |
---|
680 | </blockquote> |
---|
681 | <p>Furthermore, the pointer returned by <code>release()</code> would be difficult |
---|
682 | to deallocate reliably, as the source <b>shared_ptr</b> could have been created |
---|
683 | with a custom deleter.<BR> |
---|
684 | </p> |
---|
685 | <P><b>Q.</b> Why is <code>operator->()</code> const, but its return value is a |
---|
686 | non-const pointer to the element type?</P> |
---|
687 | <P> |
---|
688 | <b>A.</b> Shallow copy pointers, including raw pointers, typically don't |
---|
689 | propagate constness. It makes little sense for them to do so, as you can always |
---|
690 | obtain a non-const pointer from a const one and then proceed to modify the |
---|
691 | object through it.<b>shared_ptr</b> is "as close to raw pointers as possible |
---|
692 | but no closer".<BR> |
---|
693 | <BR> |
---|
694 | </P> |
---|
695 | <hr> |
---|
696 | <p> |
---|
697 | $Date: 2006/03/19 19:52:00 $</p> |
---|
698 | <p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. |
---|
699 | Copyright 2002-2005 Peter Dimov. Permission to copy, use, modify, sell and |
---|
700 | distribute this document is granted provided this copyright notice appears in |
---|
701 | all copies. This document is provided "as is" without express or implied |
---|
702 | warranty, and with no claim as to its suitability for any purpose.</small></p> |
---|
703 | </body> |
---|
704 | </html> |
---|