2002-02-02 18:36:12 +00:00
|
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
|
|
|
2000-07-27 14:27:00 +00:00
|
|
|
<html>
|
|
|
|
|
|
|
|
<head>
|
2002-02-02 18:36:12 +00:00
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
2000-07-27 14:27:00 +00:00
|
|
|
<title>shared_ptr</title>
|
|
|
|
</head>
|
|
|
|
|
|
|
|
<body bgcolor="#FFFFFF" text="#000000">
|
|
|
|
|
2002-02-02 18:36:12 +00:00
|
|
|
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86">shared_ptr class template</h1>
|
|
|
|
|
|
|
|
<p><a href="#Introduction">Introduction</a><br>
|
|
|
|
<a href="#Synopsis">Synopsis</a><br>
|
2001-07-12 19:51:53 +00:00
|
|
|
<a href="#Members">Members</a><br>
|
2002-02-02 18:36:12 +00:00
|
|
|
<a href="#functions">Free Functions</a><br>
|
|
|
|
<a href="#example">Example</a><br>
|
2001-07-12 19:51:53 +00:00
|
|
|
<a href="#Handle/Body">Handle/Body Idiom</a><br>
|
2002-01-11 16:15:09 +00:00
|
|
|
<a href="#FAQ">Frequently Asked Questions</a><br>
|
|
|
|
<a href="smarttests.htm">Smart Pointer Timings</a></p>
|
2002-02-02 18:36:12 +00:00
|
|
|
|
2001-07-12 19:51:53 +00:00
|
|
|
<h2><a name="Introduction">Introduction</a></h2>
|
2002-02-02 18:36:12 +00:00
|
|
|
|
|
|
|
<p>The <b>shared_ptr</b> class template stores a pointer to a dynamically allocated
|
|
|
|
object. (Dynamically allocated objects are allocated with the C++ <b>new</b>
|
|
|
|
expression.) The object pointed to is guaranteed to be deleted when
|
|
|
|
the last <b>shared_ptr</b> pointing to it is destroyed or reset.
|
|
|
|
See the <a href="#example">example</a>.</p>
|
|
|
|
|
|
|
|
<p>Every <b>shared_ptr</b> meets the <b>CopyConstructible</b>
|
|
|
|
and <b>Assignable</b> requirements of the C++ Standard Library, and so
|
|
|
|
can be used in standard library containers. Comparison operators
|
|
|
|
are supplied so that <b>shared_ptr</b> works with
|
|
|
|
the standard library's associative containers.</p>
|
|
|
|
|
|
|
|
<p>Normally, a <b>shared_ptr</b> cannot correctly hold a pointer to a
|
|
|
|
dynamically allocated array. See <a href="shared_array.htm"><b>shared_array</b></a>
|
2000-07-27 14:27:00 +00:00
|
|
|
for that usage.</p>
|
|
|
|
|
2002-02-02 18:36:12 +00:00
|
|
|
<p>Because the implementation uses reference counting, <b>shared_ptr</b> will not work
|
|
|
|
correctly with cyclic data structures. For example, if <b>main()</b> holds a <b>shared_ptr</b>
|
|
|
|
to <b>A</b>, which directly or indirectly holds a <b>shared_ptr</b> back to <b>A</b>,
|
|
|
|
<b>A</b>'s use count will be 2. Destruction of the original <b>shared_ptr</b>
|
|
|
|
will leave <b>A</b> dangling with a use count of 1.</p>
|
2000-07-27 14:27:00 +00:00
|
|
|
|
2002-02-02 18:36:12 +00:00
|
|
|
<p>The class template is parameterized on <b>T</b>, the type of the object
|
|
|
|
pointed to. <b>T</b> must meet the smart pointer
|
|
|
|
<a href="smart_ptr.htm#Common requirements">common requirements</a>.
|
|
|
|
<b>T</b> may be <b>void</b>, but in that case, either an explicit delete
|
|
|
|
function must be passed in, or the pointed-to object must have a trivial destructor.</p>
|
|
|
|
|
|
|
|
<h2><a name="Synopsis">Synopsis</a></h2>
|
|
|
|
|
|
|
|
<pre>namespace boost {
|
|
|
|
|
|
|
|
template<typename T> class shared_ptr {
|
|
|
|
|
|
|
|
public:
|
|
|
|
typedef T <a href="#element_type">element_type</a>;
|
|
|
|
|
|
|
|
explicit <a href="#constructors">shared_ptr</a>(T * p = 0);
|
|
|
|
template<typename D> <a href="#constructors">shared_ptr</a>(T * p, D d);
|
|
|
|
<a href="#destructor">~shared_ptr</a>(); // never throws
|
|
|
|
|
|
|
|
<a href="#constructors">shared_ptr</a>(shared_ptr const & r); // never throws
|
|
|
|
template<typename Y> <a href="#constructors">shared_ptr</a>(shared_ptr<Y> const & r); // never throws
|
|
|
|
template<typename Y> <a href="#constructors">shared_ptr</a>(std::auto_ptr<Y> & r);
|
|
|
|
|
|
|
|
shared_ptr & <a href="#assignment">operator=</a>(shared_ptr const & r); // never throws
|
|
|
|
template<typename Y> shared_ptr & <a href="#assignment">operator=</a>(shared_ptr<Y> const & r); // never throws
|
|
|
|
template<typename Y> shared_ptr & <a href="#assignment">operator=</a>(std::auto_ptr<Y> & r);
|
|
|
|
|
|
|
|
void <a href="#reset">reset</a>(T * p = 0); // never throws
|
|
|
|
template<typename D> void <a href="#reset">reset</a>(T * p, D d); // never throws
|
|
|
|
|
|
|
|
T & <a href="#indirection">operator*</a>() const; // never throws
|
|
|
|
T * <a href="#indirection">operator-></a>() const; // never throws
|
|
|
|
T * <a href="#get">get</a>() const; // never throws
|
|
|
|
|
|
|
|
bool <a href="#unique">unique</a>() const; // never throws
|
|
|
|
long <a href="#use_count">use_count</a>() const; // never throws
|
|
|
|
|
|
|
|
void <a href="#swap">swap</a>(shared_ptr<T> & b); // never throws
|
2000-07-27 14:27:00 +00:00
|
|
|
};
|
|
|
|
|
2002-02-02 18:36:12 +00:00
|
|
|
template<typename T, typename U>
|
|
|
|
bool <a href="#operator==">operator==</a>(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
|
|
|
|
template<typename T, typename U>
|
|
|
|
bool <a href="#operator!=">operator!=</a>(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
|
|
|
|
template<typename T, typename U>
|
|
|
|
bool <a href="#operator<">operator<</a>(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
|
|
|
|
|
|
|
|
template<typename T> void <a href="#free-swap">swap</a>(shared_ptr<T> & a, shared_ptr<T> & b); // never throws
|
|
|
|
|
|
|
|
template<typename T, typename U>
|
|
|
|
shared_ptr<T> <a href="#shared_static_cast">shared_static_cast</a>(shared_ptr<U> const & r); // never throws
|
|
|
|
template<typename T, typename U>
|
|
|
|
shared_ptr<T> <a href="#shared_dynamic_cast">shared_dynamic_cast</a>(shared_ptr<U> const & r);
|
|
|
|
|
|
|
|
}</pre>
|
|
|
|
|
|
|
|
<h2><a name="Members">Members</a></h2>
|
|
|
|
|
|
|
|
<h3><a name="element_type">element_type</a></h3>
|
2000-07-27 14:27:00 +00:00
|
|
|
<pre>typedef T element_type;</pre>
|
|
|
|
<p>Provides the type of the stored pointer.</p>
|
2002-02-02 18:36:12 +00:00
|
|
|
|
|
|
|
<h3><a name="constructors">constructors</a></h3>
|
|
|
|
|
|
|
|
<pre>explicit shared_ptr(T * p = 0);</pre>
|
|
|
|
<p>Constructs a <b>shared_ptr</b>, storing a copy of <b>p</b>, which
|
|
|
|
must be a pointer to an object that was allocated via a C++ <b>new</b> expression or be 0.
|
|
|
|
Afterwards, the <a href="#use_count">use count</a> is 1 (even if p == 0; see <a href="#destructor">~shared_ptr</a>).
|
|
|
|
The only exception which may be thrown by this constructor is <b>std::bad_alloc</b>.
|
|
|
|
If an exception is thrown, <b>delete p</b> is called.</p>
|
|
|
|
|
|
|
|
<pre>template<typename D> shared_ptr(T * p, D d);</pre>
|
|
|
|
<p>Constructs a <b>shared_ptr</b>, storing a copy of <b>p</b> and of <b>d</b>.
|
|
|
|
Afterwards, the <a href="#use_count">use count</a> is 1.
|
2002-02-03 17:46:08 +00:00
|
|
|
<b>D</b>'s copy constructor and destructor must not throw.
|
2002-02-02 18:36:12 +00:00
|
|
|
When the the time comes to delete the object pointed to by <b>p</b>, the object
|
|
|
|
<b>d</b> is used in the statement <b>d(p)</b>. Invoking the object <b>d</b> with
|
|
|
|
parameter <b>p</b> in this way must not throw.
|
|
|
|
The only exception which may be thrown by this constructor is <b>std::bad_alloc</b>.
|
|
|
|
If an exception is thrown, <b>d(p)</b> is called.</p>
|
|
|
|
|
|
|
|
<pre>shared_ptr(shared_ptr const & r); // never throws
|
|
|
|
template<typename Y> shared_ptr(shared_ptr<Y> const & r); // never throws
|
|
|
|
template<typename Y> shared_ptr(std::auto_ptr<Y> & r);</pre>
|
|
|
|
<p>Constructs a <b>shared_ptr</b>, as if by storing a copy of the
|
|
|
|
pointer stored in <b>r</b>. Afterwards, the <a href="#use_count">use count</a>
|
|
|
|
for all copies is 1 more than the initial use count, or 1
|
|
|
|
in the <b>auto_ptr</b> case. In the <b>auto_ptr</b> case, <b>r.release()</b>
|
|
|
|
is called.
|
|
|
|
The only exception which may be thrown is <b>std::bad_alloc</b>,
|
|
|
|
which may be thrown during construction from <b>auto_ptr</b>.
|
|
|
|
If an exception is thrown, the constructor has no effect.</p>
|
|
|
|
|
|
|
|
<h3><a name="destructor">destructor</a></h3>
|
|
|
|
|
|
|
|
<pre>~shared_ptr(); // never throws</pre>
|
|
|
|
<p>Decrements the <a href="#use_count">use count</a>. Then, if the use count is 0,
|
|
|
|
deletes the object pointed to by the stored pointer.
|
|
|
|
Note that <b>delete</b> on a pointer with a value of 0 is harmless.
|
|
|
|
<b>T</b> need not be a complete type.
|
|
|
|
The guarantee that this does not throw exceptions depends on the requirement that the
|
|
|
|
deleted object's destructor does not throw exceptions.
|
|
|
|
See the smart pointer <a href="smart_ptr.htm#Common requirements">common requirements</a>.</p>
|
|
|
|
|
|
|
|
<h3><a name="operator=">assignment</a></h3>
|
|
|
|
|
|
|
|
<pre>shared_ptr & <a href="#assignment">operator=</a>(shared_ptr const & r); // never throws
|
|
|
|
template<typename Y> shared_ptr & <a href="#assignment">operator=</a>(shared_ptr<Y> const & r); // never throws
|
|
|
|
template<typename Y> shared_ptr & <a href="#assignment">operator=</a>(std::auto_ptr<Y> & r);</pre>
|
|
|
|
<p>Constructs a new <b>shared_ptr</b> as described <a href="#constructors">above</a>,
|
|
|
|
then replaces this <b>shared_ptr</b> with the new one, destroying the replaced object.
|
|
|
|
The only exception which may be thrown is <b>std::bad_alloc</b>,
|
|
|
|
which may be thrown during assignment from <b>auto_ptr</b>.
|
|
|
|
If an exception is thrown, the assignment has no effect.</p>
|
|
|
|
|
|
|
|
<h3><a name="reset">reset</a></h3>
|
|
|
|
|
|
|
|
<pre>void reset(T * p = 0);</pre>
|
|
|
|
<p>Constructs a new <b>shared_ptr</b> as described <a href="#constructors">above</a>,
|
|
|
|
then replaces this <b>shared_ptr</b> with the new one, destroying the replaced object.
|
|
|
|
The only exception which may be thrown is <b>std::bad_alloc</b>. If
|
|
|
|
an exception is thrown, <b>delete p</b> is called.</p>
|
|
|
|
|
|
|
|
<pre>template<typename D> void reset(T * p, D d);</pre>
|
|
|
|
<p>Constructs a new <b>shared_ptr</b> as described <a href="#constructors">above</a>,
|
|
|
|
then replaces this <b>shared_ptr</b> with the new one, destroying the replaced object.
|
|
|
|
<b>D</b>'s copy constructor must not throw.
|
|
|
|
The only exception which may be thrown is <b>std::bad_alloc</b>. If
|
|
|
|
an exception is thrown, <b>d(p)</b> is called.</p>
|
|
|
|
|
|
|
|
<h3><a name="indirection">indirection</a></h3>
|
|
|
|
<pre>T & operator*() const; // never throws</pre>
|
|
|
|
<p>Returns a reference to the object pointed to by the stored pointer.
|
|
|
|
Behavior is undefined if the stored pointer is 0.</p>
|
|
|
|
<pre>T * operator->() const; // never throws</pre>
|
|
|
|
<p>Returns the stored pointer. Behavior is undefined if the stored pointer is 0.</p>
|
|
|
|
|
|
|
|
<h3><a name="get">get</a></h3>
|
|
|
|
<pre>T * get() const; // never throws</pre>
|
|
|
|
<p>Returns the stored pointer.
|
|
|
|
<b>T</b> need not be a complete type.
|
|
|
|
See the smart pointer
|
|
|
|
<a href="smart_ptr.htm#Common requirements">common requirements</a>.</p>
|
|
|
|
|
|
|
|
<h3><a name="unique">unique</a></h3>
|
|
|
|
<pre>bool unique() const; // never throws</pre>
|
|
|
|
<p>Returns true if no other <b>shared_ptr</b> is sharing ownership of
|
|
|
|
the stored pointer, false otherwise.
|
|
|
|
<b>T</b> need not be a complete type.
|
|
|
|
See the smart pointer
|
|
|
|
<a href="smart_ptr.htm#Common requirements">common requirements</a>.</p>
|
|
|
|
|
|
|
|
<h3><a name="use_count">use_count</a></h3>
|
|
|
|
<pre>long use_count() const; // never throws</pre>
|
|
|
|
<p>Returns the number of <b>shared_ptr</b> objects sharing ownership of the
|
|
|
|
stored pointer.
|
|
|
|
<b>T</b> need not be a complete type.
|
|
|
|
See the smart pointer
|
|
|
|
<a href="smart_ptr.htm#Common requirements">common requirements</a>.</p>
|
|
|
|
<p>Because <b>use_count</b> is not necessarily efficient to implement for
|
|
|
|
implementations of <b>shared_ptr</b> that do not use an explicit reference
|
|
|
|
count, it might be removed from some future version. Thus it should
|
|
|
|
be used for debugging purposes only, and not production code.</p>
|
|
|
|
|
|
|
|
<h3><a name="swap">swap</a></h3>
|
|
|
|
<pre>void swap(shared_ptr & b); // never throws</pre>
|
|
|
|
<p>Exchanges the contents of the two smart pointers.
|
|
|
|
<b>T</b> need not be a complete type.
|
|
|
|
See the smart pointer
|
|
|
|
<a href="smart_ptr.htm#Common requirements">common requirements</a>.</p>
|
|
|
|
|
|
|
|
<h2><a name="functions">Free Functions</a></h2>
|
|
|
|
|
|
|
|
<h3><a name="comparison">comparison</a></h3>
|
|
|
|
<pre>template<typename T, typename U>
|
|
|
|
bool <a href="#operator==">operator==</a>(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
|
|
|
|
template<typename T, typename U>
|
|
|
|
bool <a href="#operator!=">operator!=</a>(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws
|
|
|
|
template<typename T, typename U>
|
|
|
|
bool <a href="#operator<">operator<</a>(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws</pre>
|
|
|
|
<p>Compares the stored pointers of the two smart pointers.
|
|
|
|
<b>T</b> need not be a complete type.
|
|
|
|
See the smart pointer
|
|
|
|
<a href="smart_ptr.htm#Common requirements">common requirements</a>.</p>
|
|
|
|
<p>The <b>operator<</b> overload is provided to define an ordering so that <b>shared_ptr</b>
|
|
|
|
objects can be used in associative containers such as <b>std::map</b>.
|
2002-02-04 22:52:48 +00:00
|
|
|
The implementation uses <b>std::less<T *></b> to perform the
|
2002-02-02 18:36:12 +00:00
|
|
|
comparison. This ensures that the comparison is handled correctly, since the
|
|
|
|
standard mandates that relational operations on pointers are unspecified (5.9 [expr.rel]
|
2002-02-04 22:52:48 +00:00
|
|
|
paragraph 2) but <b>std::less<></b> on pointers is well-defined (20.3.3 [lib.comparisons]
|
2002-02-02 18:36:12 +00:00
|
|
|
paragraph 8).</p>
|
|
|
|
|
|
|
|
<h3><a name="free-swap">swap</a></h3>
|
|
|
|
<pre>template<typename T>
|
|
|
|
void swap(shared_ptr<T> & a, shared_ptr<T> & b) // never throws</pre>
|
|
|
|
<p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>.
|
|
|
|
Provided as an aid to generic programming.</p>
|
|
|
|
|
|
|
|
<h3><a name="shared_static_cast">shared_static_cast</a></h3>
|
|
|
|
<pre>template<typename T, typename U>
|
|
|
|
shared_ptr<T> <a href="#shared_static_cast">shared_static_cast</a>(shared_ptr<U> const & r); // never throws</pre>
|
|
|
|
<p>Perform a <b>static_cast</b> on the stored pointer, returning another <b>shared_ptr</b>.
|
|
|
|
The resulting smart pointer will share its use count with the original pointer.</p>
|
|
|
|
<p>Note that the seemingly equivalent expression</p>
|
|
|
|
<blockquote><code>shared_ptr<T>(static_cast<T*>(r.get()))</code></blockquote>
|
|
|
|
<p>will eventually result in undefined behavior, attempting to delete the same object twice.</p>
|
|
|
|
|
|
|
|
<h3><a name="shared_dynamic_cast">shared_dynamic_cast</a></h3>
|
|
|
|
<pre>template<typename T, typename U>
|
|
|
|
shared_ptr<T> <a href="#shared_dynamic_cast">shared_dynamic_cast</a>(shared_ptr<U> const & r);</pre>
|
|
|
|
<p>Perform a <b>dynamic_cast</b> on the stored pointer, returning another <b>shared_ptr</b>.
|
|
|
|
The resulting smart pointer will share its use count with the original pointer unless the result of the
|
|
|
|
cast is 0. The only exception which may be thrown is <b>std::bad_alloc</b>, which may be thrown during the
|
|
|
|
construction of the new <b>shared_ptr</b> if the result of the cast is 0. If an exception is thrown, the
|
|
|
|
cast has no effect.</p>
|
|
|
|
<p>Note that the seemingly equivalent expression</p>
|
|
|
|
<blockquote><code>shared_ptr<T>(dynamic_cast<T*>(r.get()))</code></blockquote>
|
|
|
|
<p>will eventually result in undefined behavior, attempting to delete the same object twice.</p>
|
|
|
|
|
|
|
|
<h2><a name="example">Example</a></h2>
|
|
|
|
|
|
|
|
<p>See <a href="shared_ptr_example.cpp">shared_ptr_example.cpp</a> for a complete example program.
|
|
|
|
The program builds a <b>std::vector</b> and <b>std::set</b> of <b>shared_ptr</b> objects.</p>
|
|
|
|
|
|
|
|
<p>Note that after the containers have been populated, some of the <b>shared_ptr</b> objects
|
|
|
|
will have a use count of 1 rather than a use count of 2, since the set is a <b>std::set</b>
|
|
|
|
rather than a <b>std::multiset</b>, and thus does not contain duplicate entries.
|
|
|
|
Furthermore, the use count may be even higher
|
|
|
|
at various times while <b>push_back</b> and <b>insert</b> container operations are performed.
|
2001-02-09 14:39:43 +00:00
|
|
|
More complicated yet, the container operations may throw exceptions under a
|
2002-02-02 18:36:12 +00:00
|
|
|
variety of circumstances. Getting the memory management and exception handling in this
|
|
|
|
example right without a smart pointer would be a nightmare.</p>
|
|
|
|
|
2001-05-24 18:42:25 +00:00
|
|
|
<h2><a name="Handle/Body">Handle/Body</a> Idiom</h2>
|
2002-02-02 18:36:12 +00:00
|
|
|
|
2001-05-24 18:42:25 +00:00
|
|
|
<p>One common usage of <b>shared_ptr</b> is to implement a handle/body (also
|
|
|
|
called pimpl) idiom which avoids exposing the body (implementation) in the header
|
|
|
|
file.</p>
|
2002-02-02 18:36:12 +00:00
|
|
|
|
2001-05-24 18:42:25 +00:00
|
|
|
<p>The <a href="shared_ptr_example2_test.cpp">shared_ptr_example2_test.cpp</a>
|
|
|
|
sample program includes a header file, <a href="shared_ptr_example2.hpp">shared_ptr_example2.hpp</a>,
|
|
|
|
which uses a <b>shared_ptr<></b> to an incomplete type to hide the
|
2002-02-02 18:36:12 +00:00
|
|
|
implementation. The
|
|
|
|
instantiation of member functions which require a complete type occurs in the
|
|
|
|
<a href="shared_ptr_example2.cpp">shared_ptr_example2.cpp</a>
|
|
|
|
implementation file.
|
|
|
|
Note that there is no need for an explicit destructor.
|
|
|
|
Unlike ~scoped_ptr, ~shared_ptr does not require that <b>T</b> be a complete type.</p>
|
|
|
|
|
2001-07-12 19:51:53 +00:00
|
|
|
<h2><a name="FAQ">Frequently Asked Questions</a></h2>
|
2002-02-02 18:36:12 +00:00
|
|
|
|
2001-07-13 14:07:08 +00:00
|
|
|
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> have template parameters supplying
|
2001-05-24 18:42:25 +00:00
|
|
|
traits or policies to allow extensive user customization?<br>
|
2002-02-02 18:36:12 +00:00
|
|
|
<b>A.</b> Parameterization discourages users. The <b>shared_ptr</b> template is
|
2001-05-24 18:42:25 +00:00
|
|
|
carefully crafted to meet common needs without extensive parameterization.
|
2002-02-02 18:36:12 +00:00
|
|
|
Some day a highly configurable smart pointer may be invented that is also very
|
|
|
|
easy to use and very hard to misuse. Until then, <b>shared_ptr</b> is the
|
|
|
|
smart pointer of choice for a wide range of applications. (Those
|
|
|
|
interested in policy based smart pointers should read
|
|
|
|
<a href="http://cseng.aw.com/book/0,,0201704315,00.html">Modern C++ Design</a> by Andrei Alexandrescu.)</p>
|
|
|
|
|
2001-07-13 14:07:08 +00:00
|
|
|
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> use a linked list implementation?<br>
|
|
|
|
<b>A.</b> A linked list implementation does not offer enough advantages to
|
2002-02-02 18:36:12 +00:00
|
|
|
offset the added cost of an extra pointer. See <a href="smarttests.htm">timings</a>
|
2001-07-12 19:51:53 +00:00
|
|
|
page.</p>
|
2002-02-02 18:36:12 +00:00
|
|
|
|
|
|
|
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> (or any of the other Boost smart pointers)
|
2001-05-24 18:42:25 +00:00
|
|
|
supply an automatic conversion to <b>T*</b>?<br>
|
2001-07-13 14:07:08 +00:00
|
|
|
<b>A.</b> Automatic conversion is believed to be too error prone.</p>
|
2002-02-02 18:36:12 +00:00
|
|
|
|
2001-07-13 14:07:08 +00:00
|
|
|
<p><b>Q.</b> Why does <b>shared_ptr</b> supply use_count()?<br>
|
|
|
|
<b>A.</b> As an aid to writing test cases and debugging displays. One of the
|
|
|
|
progenitors had use_count(), and it was useful in tracking down bugs in a
|
|
|
|
complex project that turned out to have cyclic-dependencies.</p>
|
2002-02-02 18:36:12 +00:00
|
|
|
|
2001-07-13 16:32:34 +00:00
|
|
|
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> specify complexity requirements?<br>
|
2002-02-02 18:36:12 +00:00
|
|
|
<b>A.</b> Because complexity requirements limit implementors and complicate the
|
|
|
|
specification without apparent benefit to <b>shared_ptr</b> users.
|
|
|
|
For example, error-checking implementations might become non-conforming if they
|
2001-07-13 16:32:34 +00:00
|
|
|
had to meet stringent complexity requirements.</p>
|
2002-02-02 18:36:12 +00:00
|
|
|
|
2002-01-11 20:20:07 +00:00
|
|
|
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> provide a release() function?<br>
|
|
|
|
<b>A.</b> <b>shared_ptr</b> cannot give away ownership unless it's unique()
|
|
|
|
because the other copy will still destroy the object.</p>
|
|
|
|
<p>Consider:</p>
|
2002-02-02 18:36:12 +00:00
|
|
|
<blockquote><pre>shared_ptr<int> a(new int);
|
2002-01-11 20:20:07 +00:00
|
|
|
shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2
|
|
|
|
|
|
|
|
int * p = a.release();
|
|
|
|
|
2002-02-02 18:36:12 +00:00
|
|
|
// Who owns p now? b will still call delete on it in its destructor.</pre></blockquote>
|
|
|
|
|
2001-07-13 16:32:34 +00:00
|
|
|
<p><b>Q.</b> Why doesn't <b>shared_ptr</b> provide (your pet feature here)?<br>
|
2002-02-02 18:36:12 +00:00
|
|
|
<b>A.</b> Because (your pet feature here) would mandate a reference counted
|
|
|
|
implementation or a linked list implementation, or some other specific implementation.
|
|
|
|
This is not the intent.</p>
|
|
|
|
|
2000-07-27 14:27:00 +00:00
|
|
|
<hr>
|
2002-02-02 18:36:12 +00:00
|
|
|
|
|
|
|
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->1 February 2002<!--webbot bot="Timestamp" i-checksum="38439" endspan --></p>
|
|
|
|
|
|
|
|
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
|
|
|
Permission to copy, use, modify, sell and distribute this document is granted
|
|
|
|
provided this copyright notice appears in all copies.
|
|
|
|
This document is provided "as is" without express or implied warranty,
|
|
|
|
and with no claim as to its suitability for any purpose.</p>
|
2000-07-27 14:27:00 +00:00
|
|
|
|
|
|
|
</body>
|
|
|
|
|
2002-02-02 18:36:12 +00:00
|
|
|
</html>
|