Start rewriting documentation in asciidoc

This commit is contained in:
Peter Dimov
2017-06-12 01:58:08 +03:00
parent aec76051f8
commit 0dfb4dad0f
40 changed files with 518 additions and 4712 deletions

View File

@ -1,88 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Smart Pointer Changes</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0">Smart Pointer Changes</h1>
<p>The February 2002 change to the Boost smart pointers introduced a number of
changes. Since the previous version of the smart pointers was in use for a long
time, it's useful to have a detailed list of what changed from a library user's
point of view.</p>
<p>Note that for compilers that don't support member templates well enough, a
separate implementation is used that lacks many of the new features and is more
like the old version.</p>
<h2>Features Requiring Code Changes to Take Advantage</h2>
<ul>
<li>
The smart pointer class templates now each have their own header file. For
compatibility, the <a href="../../boost/smart_ptr.hpp">&lt;boost/smart_ptr.hpp&gt;</a>
header now includes the headers for the four classic smart pointer class
templates.
<li>
The <b>weak_ptr</b>
template was added.
<li>
The new <b>shared_ptr</b> and <b>shared_array</b> relax the requirement that
the pointed-to object's destructor must be visible when instantiating the <b>shared_ptr</b>
destructor. This makes it easier to have shared_ptr members in classes without
explicit destructors.
<li>
A custom deallocator can be passed in when creating a <b>shared_ptr</b> or <b>shared_array</b>.
<li>
<b>shared_static_cast</b> and <b>shared_dynamic_cast</b> function templates are
provided which work for <b>shared_ptr</b> and <b>weak_ptr</b> as <b>static_cast</b>
and <b>dynamic_cast</b>
do for pointers.
<li>
The self-assignment misfeature has been removed from <b>shared_ptr::reset</b>,
although it is still present in <b>scoped_ptr</b>, and in <b>std::auto_ptr</b>.
Calling <b>reset</b> with a pointer to the object that's already owned by the <b>shared_ptr</b>
results in undefined behavior (an assertion, or eventually a double-delete if
assertions are off).
<li>
The <b>BOOST_SMART_PTR_CONVERSION</b>
feature has been removed.
<li>
<b>shared_ptr&lt;void&gt;</b> is now allowed.</li>
</ul>
<h2>Features That Improve Robustness</h2>
<ul>
<li>
The manipulation of use counts is now <a name="threadsafe">thread safe</a> on
Windows, Linux, and platforms that support pthreads. See the <a href="../../boost/detail/atomic_count.hpp">
&lt;boost/detail/atomic_count.hpp&gt;</a>
file for details
<li>
The new shared_ptr will always delete the object using the pointer it was
originally constructed with. This prevents subtle problems that could happen if
the last <b>shared_ptr</b> was a pointer to a sub-object of a class that did
not have a virtual destructor.</li>
</ul>
<h2>Implementation Details</h2>
<ul>
<li>
Some bugs in the assignment operator implementations and in <b>reset</b>
have been fixed by using the "copy and swap" idiom.
<li>
Assertions have been added to check preconditions of various functions;
however, since these use the new <a href="../../boost/assert.hpp">&lt;boost/assert.hpp&gt;</a>
header, the assertions are disabled by default.
<li>
The partial specialization of <b>std::less</b> has been replaced by <b>operator&lt;</b>
overloads which accomplish the same thing without relying on undefined
behavior.
<li>
The incorrect overload of <b>std::swap</b> has been replaced by <b>boost::swap</b>,
which has many of the same advantages for generic programming but does not
violate the C++ standard.</li>
</ul>
<hr>
<p>$Date$</p>
<p><small>Copyright 2002 Darin Adler. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

26
doc/Jamfile Normal file
View File

@ -0,0 +1,26 @@
# Copyright 2017 Peter Dimov
#
# Distributed under the Boost Software License, Version 1.0.
#
# See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt
project doc/smart_ptr ;
import asciidoctor ;
html smart_ptr.html : smart_ptr.adoc ;
install html_ : smart_ptr.html : <location>html ;
pdf smart_ptr.pdf : smart_ptr.adoc ;
explicit smart_ptr.pdf ;
install pdf_ : smart_ptr.pdf : <location>pdf ;
explicit pdf_ ;
###############################################################################
alias boostdoc ;
explicit boostdoc ;
alias boostrelease : html_ ;
explicit boostrelease ;

50
doc/asciidoctor.jam Normal file
View File

@ -0,0 +1,50 @@
# Copyright 2017 Peter Dimov
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
import type ;
import scanner ;
import generators ;
import boostbook ;
# File type
type.register ASCIIDOC : asciidoc adoc ;
# Define dependency scanner
class asciidoc-scanner : common-scanner
{
rule pattern ( )
{
return "include::([^[]+)\\[" ;
}
}
scanner.register asciidoc-scanner : include ;
type.set-scanner ASCIIDOC : asciidoc-scanner ;
# Define generators
generators.register-standard asciidoctor.asciidoc-to-html : ASCIIDOC : HTML ;
generators.register-standard asciidoctor.asciidoc-to-pdf : ASCIIDOC : PDF ;
# generators.register-standard asciidoctor.asciidoc-to-docbook : ASCIIDOC : DOCBOOK ;
# Define actions
actions asciidoc-to-html
{
asciidoctor -b html -o $(1) $(2)
}
actions asciidoc-to-pdf
{
asciidoctor -r asciidoctor-pdf -b pdf -o $(1) $(2)
}
actions asciidoc-to-docbook
{
asciidoctor -b docbook -o $(1) $(2)
}

View File

@ -0,0 +1,33 @@
<style>
*:not(pre)>code { background: none; color: #600000; }
table tr.even, table tr.alt, table tr:nth-of-type(even) { background: none; }
</style>
<script>
var header = document.getElementById( 'boost-common-heading-doc' );
if( header )
{
header.style.position = 'fixed';
header.style.zIndex = '100';
var notice = document.getElementsByClassName( 'boost-common-header-notice' )[ 0 ];
if( notice )
{
notice.style.position = 'fixed';
notice.style.zIndex = '101';
}
var toc = document.getElementById( 'toc' );
if( toc )
{
toc.style.top = '101px';
}
}
</script>

70
doc/smart_ptr.adoc Normal file
View File

@ -0,0 +1,70 @@
////
Copyright 2017 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
# Boost.SmartPtr: Smart Pointer Library
Greg Colvin, Beman Dawes, Peter Dimov, Glen Fernandes
:toc: left
:toclevels: 3
:idprefix:
:listing-caption: Code Example
:table-caption: Illustration
:docinfo: private-footer
:leveloffset: +1
include::smart_ptr/introduction.adoc[]
include::smart_ptr/scoped_ptr.adoc[]
include::smart_ptr/scoped_array.adoc[]
include::smart_ptr/shared_ptr.adoc[]
include::smart_ptr/weak_ptr.adoc[]
include::smart_ptr/make_shared.adoc[]
include::smart_ptr/enable_shared_from_this.adoc[]
include::smart_ptr/make_unique.adoc[]
include::smart_ptr/intrusive_ptr.adoc[]
include::smart_ptr/intrusive_ref_counter.adoc[]
include::smart_ptr/pointer_cast.adoc[]
include::smart_ptr/pointer_to_other.adoc[]
// appendix
include::smart_ptr/techniques.adoc[]
// appendix
include::smart_ptr/history.adoc[]
// appendix, deprecated
include::smart_ptr/shared_array.adoc[]
:leveloffset: -1
[appendix]
## Copyright and License
This documentation is
* Copyright 1999 Greg Colvin
* Copyright 1999 Beman Dawes
* Copyright 2002 Darin Adler
* Copyright 2003-2017 Peter Dimov
* Copyright 2005, 2006 Ion Gaztañaga
* Copyright 2008 Frank Mori Hess
* Copyright 2012-2017 Glen Fernandes
* Copyright 2013 Andrey Semashev
and is distributed under the http://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0].

View File

@ -0,0 +1,15 @@
////
Copyright 2017 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[#enable_shared_from_this]
# enable_shared_from_this
:toc:
:toc-title:
:idprefix:

View File

@ -0,0 +1,89 @@
////
Copyright 1999 Greg Colvin and Beman Dawes
Copyright 2002 Darin Adler
Copyright 2017 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[appendix,#history]
# History and Acknowledgments
:idprefix:
## Summer 1994
Greg Colvin http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf[proposed]
to the {cpp} Standards Committee classes named `auto_ptr` and `counted_ptr` which were very
similar to what we now call `scoped_ptr` and `shared_ptr`. In one of the very few cases
where the Library Working Group's recommendations were not followed by the full committee,
`counted_ptr` was rejected and surprising transfer-of-ownership semantics were added to `auto_ptr`.
## October 1998
Beman Dawes proposed reviving the original semantics under the names `safe_ptr` and `counted_ptr`,
meeting of Per Andersson, Matt Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis,
Dietmar Kühl, Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new class
names were finalized, it was decided that there was no need to exactly follow the `std::auto_ptr`
interface, and various function signatures and semantics were finalized.
Over the next three months, several implementations were considered for `shared_ptr`, and discussed
on the http://www.boost.org/[boost.org] mailing list. The implementation questions revolved around
the reference count which must be kept, either attached to the pointed to object, or detached elsewhere.
Each of those variants have themselves two major variants:
* Direct detached: the `shared_ptr` contains a pointer to the object, and a pointer to the count.
* Indirect detached: the `shared_ptr` contains a pointer to a helper object, which in turn contains a pointer to the object and the count.
* Embedded attached: the count is a member of the object pointed to.
* Placement attached: the count is attached via operator new manipulations.
Each implementation technique has advantages and disadvantages. We went so far as to run various timings
of the direct and indirect approaches, and found that at least on Intel Pentium chips there was very little
measurable difference. Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar Kühl
suggested an elegant partial template specialization technique to allow users to choose which implementation
they preferred, and that was also experimented with.
But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage users", and in the end we choose
to supply only the direct implementation.
## May 1999
In April and May, 1999, Valentin Bonnard and David Abrahams made a number of suggestions resulting in numerous improvements.
## September 1999
Luis Coelho provided `shared_ptr::swap` and `shared_array::swap`.
## November 1999
Darin Adler provided `operator ==`, `operator !=`, and `std::swap` and `std::less` specializations for shared types.
## May 2001
Vladimir Prus suggested requiring a complete type on destruction. Refinement evolved in discussions including Dave Abrahams,
Greg Colvin, Beman Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and others.
## January 2002
Peter Dimov reworked all four classes, adding features, fixing bugs, splitting them into four separate headers, and adding
`weak_ptr`.
## November 2012
Glen Fernandes provided implementations of `make_shared` and `allocate_shared` for arrays. They achieve a single allocation
for an array that can be initialized with constructor arguments or initializer lists as well as overloads for default initialization
and no value initialization.
## February 2014
Glen Fernandes updated overloads of `make_shared` and `allocate_shared` to conform to the specification in {cpp} standard paper
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3870.html[N3870],
and implemented `make_unique` for arrays and objects. Peter Dimov and Glen Fernandes updated the scalar and array implementations,
respectively, to resolve {cpp} standard library defect 2070.
## February 2017
Glen Fernandes rewrote `allocate_shared` and `make_shared` for arrays for a more optimal and more maintainable implementation.

View File

@ -0,0 +1,49 @@
////
Copyright 1999 Greg Colvin and Beman Dawes
Copyright 2002 Darin Adler
Copyright 2017 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[#introduction]
# Introduction
:toc:
:toc-title:
:idprefix:
Smart pointers are objects which store pointers to dynamically allocated (heap) objects.
They behave much like built-in {cpp} pointers except that they automatically delete the object
pointed to at the appropriate time. Smart pointers are particularly useful in the face of
exceptions as they ensure proper destruction of dynamically allocated objects. They can also be
used to keep track of dynamically allocated objects shared by multiple owners.
Conceptually, smart pointers are seen as owning the object pointed to, and thus responsible for
deletion of the object when it is no longer needed. As such, they are examples of the "resource
acquisition is initialization" idiom described in Bjarne Stroustrup's "The C++ Programming Language",
3rd edition, Section 14.4, Resource Management.
This library provides five smart pointer class templates:
* `scoped_ptr`, used to contain ownership of a dynamically allocated object to the current scope;
* `scoped_array`, which provides scoped ownership for a dynamically allocated array;
* `shared_ptr`, a versatile tool for managing shared ownership of an object or array;
* `weak_ptr`, a non-owning observer to a shared_ptr-managed object that can be promoted temporarily to shared_ptr;
* `intrusive_ptr`, a pointer to objects with an embedded reference count.
`shared_ptr` and `weak_ptr` are part of the {cpp} standard since its 2011 iteration.
In addition, the library contains the following supporting utility functions and classes:
* `make_shared`, a factory function for creating objects that returns a `shared_ptr`;
* `make_unique`, a factory function returning `std::unique_ptr`;
* `enable_shared_from_this`, a helper base class that enables the acquisition of a `shared_ptr` pointing to `this`;
* `pointer_to_other`, a helper trait for converting one smart pointer type to another;
* `static_pointer_cast` and companions, generic smart pointer casts;
* `intrusive_ref_counter`, a helper base class containing a reference count.
As a general rule, the destructor or `operator delete` for an object managed by pointers in the library
are not allowed to throw exceptions.

View File

@ -0,0 +1,15 @@
////
Copyright 2017 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[#intrusive_ptr]
# intrusive_ptr
:toc:
:toc-title:
:idprefix:

View File

@ -0,0 +1,15 @@
////
Copyright 2017 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[#intrusive_ref_counter]
# intrusive_ref_counter
:toc:
:toc-title:
:idprefix:

View File

@ -0,0 +1,15 @@
////
Copyright 2017 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[#make_shared]
# make_shared
:toc:
:toc-title:
:idprefix:

View File

@ -0,0 +1,15 @@
////
Copyright 2017 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[#make_unique]
# make_unique
:toc:
:toc-title:
:idprefix:

View File

@ -0,0 +1,15 @@
////
Copyright 2017 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[#pointer_cast]
# Generic Pointer Casts
:toc:
:toc-title:
:idprefix:

View File

@ -0,0 +1,15 @@
////
Copyright 2017 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[#pointer_to_other]
# pointer_to_other
:toc:
:toc-title:
:idprefix:

View File

@ -0,0 +1,15 @@
////
Copyright 2017 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[#scoped_array]
# scoped_array
:toc:
:toc-title:
:idprefix:

View File

@ -0,0 +1,15 @@
////
Copyright 2017 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[#scoped_ptr]
# scoped_ptr
:toc:
:toc-title:
:idprefix:

View File

@ -0,0 +1,15 @@
////
Copyright 2017 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[appendix,#shared_array]
# shared_array (deprecated)
:toc:
:toc-title:
:idprefix:

View File

@ -0,0 +1,15 @@
////
Copyright 2017 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[#shared_ptr]
# shared_ptr
:toc:
:toc-title:
:idprefix:

View File

@ -0,0 +1,15 @@
////
Copyright 2017 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[appendix,#techniques]
# Smart Pointer Programming Techniques
:toc:
:toc-title:
:idprefix:

View File

@ -0,0 +1,15 @@
////
Copyright 2017 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[#weak_ptr]
# weak_ptr
:toc:
:toc-title:
:idprefix:

View File

@ -1,110 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>enable_shared_from_this</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0" />enable_shared_from_this</h1>
<h2><a name="Purpose">Purpose</a></h2>
<p>
The header <code>&lt;boost/enable_shared_from_this.hpp&gt;</code> defines
the class template <code>enable_shared_from_this</code>. It is used as a
base class that allows a <a href="shared_ptr.htm">shared_ptr</a> or
a <a href="weak_ptr.htm">weak_ptr</a> to the current object to be obtained
from within a member function.
</p>
<p><code>enable_shared_from_this&lt;T&gt;</code> defines two member functions
called <code>shared_from_this</code> that return a <code>shared_ptr&lt;T&gt;</code>
and <code>shared_ptr&lt;T const&gt;</code>, depending on constness, to <code>this</code>.
It also defines two member functions called <code>weak_from_this</code> that return
a corresponding <code>weak_ptr</code>.
</p>
<h2><a name="Example">Example</a></h2>
<pre>
#include &lt;boost/enable_shared_from_this.hpp&gt;
#include &lt;boost/shared_ptr.hpp&gt;
#include &lt;cassert&gt;
class Y: public boost::enable_shared_from_this&lt;Y&gt;
{
public:
boost::shared_ptr&lt;Y&gt; f()
{
return shared_from_this();
}
};
int main()
{
boost::shared_ptr&lt;Y&gt; p(new Y);
boost::shared_ptr&lt;Y&gt; q = p-&gt;f();
assert(p == q);
assert(!(p &lt; q || q &lt; p)); // p and q must share ownership
}
</pre>
<h2><a name="Synopsis">Synopsis</a></h2>
<pre>
namespace boost
{
template&lt;class T&gt; class enable_shared_from_this
{
public:
shared_ptr&lt;T&gt; shared_from_this();
shared_ptr&lt;T const&gt; shared_from_this() const;
weak_ptr&lt;T&gt; weak_from_this() noexcept;
weak_ptr&lt;T const&gt; weak_from_this() const noexcept;
}
}
</pre>
<h4><code>template&lt;class T&gt; shared_ptr&lt;T&gt;
enable_shared_from_this&lt;T&gt;::shared_from_this();</code></h4>
<h4><code>template&lt;class T&gt; shared_ptr&lt;T const&gt;
enable_shared_from_this&lt;T&gt;::shared_from_this() const;</code></h4>
<blockquote>
<p>
<b>Requires:</b> <code>enable_shared_from_this&lt;T&gt;</code> must be an
accessible base class of <code>T</code>. <code>*this</code> must be a subobject
of an instance <code>t</code> of type <code>T</code>.
</p>
<p>
<b>Returns:</b> If a <code>shared_ptr</code> instance <code>p</code> that <em>owns</em>
<code>t</code> exists, a <code>shared_ptr&lt;T&gt;</code> instance <code>r</code> that shares
ownership with <code>p</code>.
</p>
<p>
<b>Postconditions:</b> <code>r.get() == this</code>.
</p>
<p>
<b>Throws:</b> <code>bad_weak_ptr</code> when no <code>shared_ptr</code> <em>owns</em> <code>*this</code>.
</p>
</blockquote>
<h4><code>template&lt;class T&gt; weak_ptr&lt;T&gt;
enable_shared_from_this&lt;T&gt;::weak_from_this() noexcept;</code></h4>
<h4><code>template&lt;class T&gt; weak_ptr&lt;T const&gt;
enable_shared_from_this&lt;T&gt;::weak_from_this() const noexcept;</code></h4>
<blockquote>
<p>
<b>Requires:</b> <code>enable_shared_from_this&lt;T&gt;</code> must be an
accessible base class of <code>T</code>. <code>*this</code> must be a subobject
of an instance <code>t</code> of type <code>T</code>.
</p>
<p>
<b>Returns:</b> If a <code>shared_ptr</code> instance <code>p</code> that <em>owns</em>
<code>t</code> exists or has existed in the past, a <code>weak_ptr&lt;T&gt;</code> instance
<code>r</code> that shares ownership with <code>p</code>. Otherwise, an empty <code>weak_ptr</code>.
</p>
</blockquote>
<hr />
<p>
<small>Copyright &copy; 2002, 2003, 2015 by Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
copy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>.</small></p>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

View File

@ -1,13 +1,13 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!DOCTYPE html>
<html>
<head>
<title>Smart Pointers</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="refresh" content="0; URL=smart_ptr.htm">
<meta http-equiv="refresh" content="0; URL=doc/html/smart_ptr.html">
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<body>
<p>
Automatic redirection failed, please go to
<a href="smart_ptr.htm">smart_ptr.htm</a>.
<a href="doc/html/smart_ptr.html">doc/html/smart_ptr.html</a>.
</p>
</body>
</html>
<!--

View File

@ -1,320 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>intrusive_ptr</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0">intrusive_ptr class template</h1>
<p>
<a href="#Introduction">Introduction</a><br>
<a href="#Synopsis">Synopsis</a><br>
<a href="#Members">Members</a><br>
<a href="#functions">Free Functions</a><br>
</p>
<h2><a name="Introduction">Introduction</a></h2>
<p>The <code>intrusive_ptr</code> class template stores a pointer to an object with an
embedded reference count. Every new <code>intrusive_ptr</code> instance increments
the reference count by using an unqualified call to the function <code>intrusive_ptr_add_ref</code>,
passing it the pointer as an argument. Similarly, when an <code>intrusive_ptr</code>
is destroyed, it calls <code>intrusive_ptr_release</code>; this function is
responsible for destroying the object when its reference count drops to zero.
The user is expected to provide suitable definitions of these two functions. On
compilers that support argument-dependent lookup, <code>intrusive_ptr_add_ref</code>
and <code>intrusive_ptr_release</code> should be defined in the namespace
that corresponds to their parameter; otherwise, the definitions need to go in
namespace <code>boost</code>. The library provides a helper base class template
<code><a href="intrusive_ref_counter.html">intrusive_ref_counter</a></code> which may
help adding support for <code>intrusive_ptr</code> to user types.</p>
<p>The class template is parameterized on <code>T</code>, the type of the object pointed
to. <code>intrusive_ptr&lt;T&gt;</code> can be implicitly converted to <code>intrusive_ptr&lt;U&gt;</code>
whenever <code>T*</code> can be implicitly converted to <code>U*</code>.</p>
<p>The main reasons to use <code>intrusive_ptr</code> are:</p>
<ul>
<li>
Some existing frameworks or OSes provide objects with embedded reference
counts;</li>
<li>
The memory footprint of <code>intrusive_ptr</code>
is the same as the corresponding raw pointer;</li>
<li>
<code>intrusive_ptr&lt;T&gt;</code> can be constructed from an arbitrary
raw pointer of type <code>T *</code>.</li></ul>
<p>As a general rule, if it isn't obvious whether <code>intrusive_ptr</code> better
fits your needs than <code>shared_ptr</code>, try a <code>shared_ptr</code>-based
design first.</p>
<h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost {
template&lt;class T&gt; class intrusive_ptr {
public:
typedef T <a href="#element_type" >element_type</a>;
<a href="#constructors" >intrusive_ptr</a>(); // never throws
<a href="#constructors" >intrusive_ptr</a>(T * p, bool add_ref = true);
<a href="#constructors" >intrusive_ptr</a>(intrusive_ptr const &amp; r);
template&lt;class Y&gt; <a href="#constructors" >intrusive_ptr</a>(intrusive_ptr&lt;Y&gt; const &amp; r);
<a href="#destructor" >~intrusive_ptr</a>();
intrusive_ptr &amp; <a href="#assignment" >operator=</a>(intrusive_ptr const &amp; r);
template&lt;class Y&gt; intrusive_ptr &amp; <a href="#assignment" >operator=</a>(intrusive_ptr&lt;Y&gt; const &amp; r);
intrusive_ptr &amp; <a href="#assignment" >operator=</a>(T * r);
void <a href="#reset" >reset</a>();
void <a href="#reset" >reset</a>(T * r);
void <a href="#reset" >reset</a>(T * r, bool add_ref);
T &amp; <a href="#indirection" >operator*</a>() const; // never throws
T * <a href="#indirection" >operator-&gt;</a>() const; // never throws
T * <a href="#get" >get</a>() const; // never throws
T * <a href="#detach" >detach</a>(); // never throws
operator <a href="#conversions" ><i>unspecified-bool-type</i></a>() const; // never throws
void <a href="#swap" >swap</a>(intrusive_ptr &amp; b); // never throws
};
template&lt;class T, class U&gt;
bool <a href="#comparison" >operator==</a>(intrusive_ptr&lt;T&gt; const &amp; a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws
template&lt;class T, class U&gt;
bool <a href="#comparison" >operator!=</a>(intrusive_ptr&lt;T&gt; const &amp; a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws
template&lt;class T&gt;
bool <a href="#comparison" >operator==</a>(intrusive_ptr&lt;T&gt; const &amp; a, T * b); // never throws
template&lt;class T&gt;
bool <a href="#comparison" >operator!=</a>(intrusive_ptr&lt;T&gt; const &amp; a, T * b); // never throws
template&lt;class T&gt;
bool <a href="#comparison" >operator==</a>(T * a, intrusive_ptr&lt;T&gt; const &amp; b); // never throws
template&lt;class T&gt;
bool <a href="#comparison" >operator!=</a>(T * a, intrusive_ptr&lt;T&gt; const &amp; b); // never throws
template&lt;class T, class U&gt;
bool <a href="#comparison" >operator&lt;</a>(intrusive_ptr&lt;T&gt; const &amp; a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws
template&lt;class T&gt; void <a href="#free-swap" >swap</a>(intrusive_ptr&lt;T&gt; &amp; a, intrusive_ptr&lt;T&gt; &amp; b); // never throws
template&lt;class T&gt; T * <a href="#get_pointer" >get_pointer</a>(intrusive_ptr&lt;T&gt; const &amp; p); // never throws
template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; <a href="#static_pointer_cast" >static_pointer_cast</a>(intrusive_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; <a href="#const_pointer_cast" >const_pointer_cast</a>(intrusive_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; <a href="#dynamic_pointer_cast" >dynamic_pointer_cast</a>(intrusive_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;class E, class T, class Y&gt;
std::basic_ostream&lt;E, T&gt; &amp; <a href="#insertion-operator" >operator&lt;&lt;</a> (std::basic_ostream&lt;E, T&gt; &amp; os, intrusive_ptr&lt;Y&gt; const &amp; p);
}</pre>
<h2><a name="Members">Members</a></h2>
<h3><a name="element_type">element_type</a></h3>
<pre>typedef T element_type;</pre>
<blockquote>
<p>Provides the type of the template parameter <code>T</code>.</p>
</blockquote>
<h3><a name="constructors">constructors</a></h3>
<pre>intrusive_ptr(); // never throws</pre>
<blockquote>
<p><b>Postconditions:</b> <code>get() == 0</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>intrusive_ptr(T * p, bool add_ref = true);</pre>
<blockquote>
<p><b>Effects:</b> <code>if(p != 0 &amp;&amp; add_ref) intrusive_ptr_add_ref(p);</code>.</p>
<p><b>Postconditions:</b> <code>get() == p</code>.</p>
</blockquote>
<pre>intrusive_ptr(intrusive_ptr const &amp; r);
template&lt;class Y&gt; intrusive_ptr(intrusive_ptr&lt;Y&gt; const &amp; r);</pre>
<blockquote>
<p><b>Effects:</b> <code>if(r.get() != 0) intrusive_ptr_add_ref(r.get());</code>.</p>
<p><b>Postconditions:</b> <code>get() == r.get()</code>.</p>
</blockquote>
<h3><a name="destructor">destructor</a></h3>
<pre>~intrusive_ptr();</pre>
<blockquote>
<p><b>Effects:</b> <code>if(get() != 0) intrusive_ptr_release(get());</code>.</p>
</blockquote>
<h3><a name="assignment">assignment</a></h3>
<pre>intrusive_ptr &amp; operator=(intrusive_ptr const &amp; r);
template&lt;class Y&gt; intrusive_ptr &amp; operator=(intrusive_ptr&lt;Y&gt; const &amp; r);
intrusive_ptr &amp; operator=(T * r);</pre>
<blockquote>
<p><b>Effects:</b> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</p>
<p><b>Returns:</b> <code>*this</code>.</p>
</blockquote>
<h3><a name="reset">reset</a></h3>
<pre>void reset();</pre>
<blockquote>
<p><b>Effects:</b> Equivalent to <code>intrusive_ptr().swap(*this)</code>.</p>
</blockquote>
<pre>void reset(T * r);</pre>
<blockquote>
<p><b>Effects:</b> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</p>
</blockquote>
<pre>void reset(T * r, bool add_ref);</pre>
<blockquote>
<p><b>Effects:</b> Equivalent to <code>intrusive_ptr(r, add_ref).swap(*this)</code>.</p>
</blockquote>
<h3><a name="indirection">indirection</a></h3>
<pre>T &amp; operator*() const; // never throws</pre>
<blockquote>
<p><b>Requirements:</b> <code>get() != 0</code>.</p>
<p><b>Returns:</b> <code>*get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>T * operator-&gt;() const; // never throws</pre>
<blockquote>
<p><b>Requirements:</b> <code>get() != 0</code>.</p>
<p><b>Returns:</b> <code>get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3><a name="get">get</a></h3>
<pre>T * get() const; // never throws</pre>
<blockquote>
<p><b>Returns:</b> the stored pointer.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3><a name="detach">detach</a></h3>
<pre>T * detach(); // never throws</pre>
<blockquote>
<p><b>Returns:</b> the stored pointer.</p>
<p><b>Throws:</b> nothing.</p>
<p><b>Postconditions:</b> <code>get() == 0</code>.</p>
<p><b>Notes:</b> The returned pointer has an elevated reference count. This
allows conversion of an <code>intrusive_ptr</code> back to a raw pointer,
without the performance overhead of acquiring and dropping an extra
reference. It can be viewed as the complement of the
non-reference-incrementing constructor.</p>
<p><b>Caution:</b> Using <code>detach</code> escapes the safety of automatic
reference counting provided by <code>intrusive_ptr</code>. It should
by used only where strictly necessary (such as when interfacing to an
existing API), and when the implications are thoroughly understood.</p>
</blockquote>
<h3><a name="conversions">conversions</a></h3>
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
<blockquote>
<p><b>Returns:</b> an unspecified value that, when used in boolean contexts, is
equivalent to <code>get() != 0</code>.</p>
<p><b>Throws:</b> nothing.</p>
<p><b>Notes:</b> This conversion operator allows <code>intrusive_ptr</code> objects to be
used in boolean contexts, like <code>if (p &amp;&amp; p-&gt;valid()) {}</code>.
The actual target type is typically a pointer to a member function, avoiding
many of the implicit conversion pitfalls.</p>
</blockquote>
<h3><a name="swap">swap</a></h3>
<pre>void swap(intrusive_ptr &amp; b); // never throws</pre>
<blockquote>
<p><b>Effects:</b> Exchanges the contents of the two smart pointers.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h2><a name="functions">Free Functions</a></h2>
<h3><a name="comparison">comparison</a></h3>
<pre>template&lt;class T, class U&gt;
bool operator==(intrusive_ptr&lt;T&gt; const &amp; a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a.get() == b.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T, class U&gt;
bool operator!=(intrusive_ptr&lt;T&gt; const &amp; a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a.get() != b.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T, class U&gt;
bool operator==(intrusive_ptr&lt;T&gt; const &amp; a, U * b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a.get() == b</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T, class U&gt;
bool operator!=(intrusive_ptr&lt;T&gt; const &amp; a, U * b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a.get() != b</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T, class U&gt;
bool operator==(T * a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a == b.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T, class U&gt;
bool operator!=(T * a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a != b.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T, class U&gt;
bool operator&lt;(intrusive_ptr&lt;T&gt; const &amp; a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>std::less&lt;T *&gt;()(a.get(), b.get())</code>.</p>
<p><b>Throws:</b> nothing.</p>
<p><b>Notes:</b> Allows <code>intrusive_ptr</code> objects to be used as keys
in associative containers.</p>
</blockquote>
<h3><a name="free-swap">swap</a></h3>
<pre>template&lt;class T&gt;
void swap(intrusive_ptr&lt;T&gt; &amp; a, intrusive_ptr&lt;T&gt; &amp; b); // never throws</pre>
<blockquote>
<p><b>Effects:</b> Equivalent to <code>a.swap(b)</code>.</p>
<p><b>Throws:</b> nothing.</p>
<p><b>Notes:</b> Matches the interface of <code>std::swap</code>. Provided as an aid to
generic programming.</p>
</blockquote>
<h3><a name="get_pointer">get_pointer</a></h3>
<pre>template&lt;class T&gt;
T * get_pointer(intrusive_ptr&lt;T&gt; const &amp; p); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>p.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
<p><b>Notes:</b> Provided as an aid to generic programming. Used by <a href="../bind/mem_fn.html">
mem_fn</a>.</p>
</blockquote>
<h3><a name="static_pointer_cast">static_pointer_cast</a></h3>
<pre>template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; static_pointer_cast(intrusive_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>intrusive_ptr&lt;T&gt;(static_cast&lt;T*&gt;(r.get()))</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3><a name="const_pointer_cast">const_pointer_cast</a></h3>
<pre>template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; const_pointer_cast(intrusive_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>intrusive_ptr&lt;T&gt;(const_cast&lt;T*&gt;(r.get()))</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3><a name="dynamic_pointer_cast">dynamic_pointer_cast</a></h3>
<pre>template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; dynamic_pointer_cast(intrusive_ptr&lt;U&gt; const &amp; r);</pre>
<blockquote>
<p><b>Returns:</b> <code>intrusive_ptr&lt;T&gt;(dynamic_cast&lt;T*&gt;(r.get()))</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3><a name="insertion-operator">operator&lt;&lt;</a></h3>
<pre>template&lt;class E, class T, class Y&gt;
std::basic_ostream&lt;E, T&gt; &amp; operator&lt;&lt; (std::basic_ostream&lt;E, T&gt; &amp; os, intrusive_ptr&lt;Y&gt; const &amp; p);</pre>
<blockquote>
<p><b>Effects:</b> <code>os &lt;&lt; p.get();</code>.</p>
<p><b>Returns:</b> <code>os</code>.</p>
</blockquote>
<hr>
<p>$Date$</p>
<p>
<small>Copyright &copy; 2003-2005, 2013 Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
copy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>.</small></p>
</body>
</html>

View File

@ -1,94 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>intrusive_ref_counter</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0">basic_intrusive_ref_counter class template</h1>
<p>
<A href="#Introduction">Introduction</A><br>
<A href="#Synopsis">Synopsis</A><br>
<A href="#Members">Members</A><br>
</p>
<h2><a name="Introduction">Introduction</a></h2>
<p>The <STRONG>intrusive_ref_counter</STRONG> class template implements a reference counter for a derived
user's class that is intended to be used with <STRONG><a href="intrusive_ptr.html">intrusive_ptr</a></STRONG>.
The base class has associated <STRONG>intrusive_ptr_add_ref</STRONG> and <STRONG>intrusive_ptr_release</STRONG> functions
which modify the reference counter as needed and destroy the user's object when the counter drops to zero.</p>
<p>The class template is parameterized on <STRONG>DerivedT</STRONG> and <STRONG>CounterPolicyT</STRONG> parameters.
The first parameter is the user's class that derives from <STRONG>intrusive_ref_counter</STRONG>. This type
is needed in order to destroy the object correctly when there are no references to it left.</p>
<p>The second parameter is a policy that defines the nature of the reference counter.
Boost.SmartPtr provides two such policies: <STRONG>thread_unsafe_counter</STRONG> and <STRONG>thread_safe_counter</STRONG>. The former
instructs the <STRONG>intrusive_ref_counter</STRONG> base class to use a counter only suitable for a single-threaded use.
Pointers to a single object that uses this kind of reference counter must not be used in different threads. The latter policy
makes the reference counter thread-safe, unless the target platform doesn't support threading. Since in modern systems support for
threading is common, the default counter policy is <STRONG>thread_safe_counter</STRONG>.</p>
<h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost {
struct thread_unsafe_counter;
struct thread_safe_counter;
template&lt;class DerivedT, class CounterPolicyT = thread_safe_counter&gt;
class intrusive_ref_counter
{
public:
<A href="#constructors" >intrusive_ref_counter</A>() = noexcept;
<A href="#constructors" >intrusive_ref_counter</A>(intrusive_ref_counter const &amp; r) = noexcept;
intrusive_ref_counter &amp; <A href="#assignment" >operator=</A>(intrusive_ref_counter const &amp; r) noexcept;
unsigned int <a href="#use_count" >use_count</a>() const noexcept;
protected:
<A href="#destructor" >~intrusive_ref_counter</A>() = default;
};
}</pre>
<h2><a name="Members">Members</a></h2>
<h3><a name="constructors">constructors</a></h3>
<pre>intrusive_ref_counter();</pre>
<blockquote>
<p><b>Postconditions:</b> <code>use_count() == 0</code>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> The pointer to the constructed object is expected to be passed to <STRONG>intrusive_ptr</STRONG>
constructor, assignment operator or <STRONG>reset()</STRONG> method, which would increment the reference counter.</P>
</blockquote>
<pre>intrusive_ref_counter(intrusive_ref_counter const &amp;);</pre>
<blockquote>
<p><b>Postconditions:</b> <code>use_count() == 0</code>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> The pointer to the constructed object is expected to be passed to <STRONG>intrusive_ptr</STRONG>
constructor, assignment operator or <STRONG>reset()</STRONG> method, which would increment the reference counter.</P>
</blockquote>
<h3><a name="destructor">destructor</a></h3>
<pre>~intrusive_ref_counter();</pre>
<BLOCKQUOTE>
<p><b>Throws:</b> nothing.</p>
<P><B>Effects:</B> Destroys the counter object.</P>
<P><B>Notes:</B> The destructor is protected so that the object can only be destroyed through the <STRONG>DerivedT</STRONG> class.</P>
</BLOCKQUOTE>
<H3><a name="assignment">assignment</a></H3>
<pre>intrusive_ref_counter &amp; operator=(intrusive_ref_counter const &amp; r) noexcept;</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Does nothing, reference counter is not modified.</P>
<P><B>Returns:</B> <code>*this</code>.</P>
</BLOCKQUOTE>
<H3><a name="use_count">use_count</a></H3>
<pre>unsigned int use_count() const noexcept;</pre>
<BLOCKQUOTE>
<p><b>Returns:</b> The current value of the reference counter.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> The returned value may not be actual in multi-threaded applications.</P>
</BLOCKQUOTE>
<hr>
<p>$Date$</p>
<p>
<small>Copyright &copy; 2013 Andrey Semashev. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

View File

@ -1,119 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>make_shared and allocate_shared</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0">make_shared and allocate_shared
function templates</h1>
<p><A href="#Introduction">Introduction</A><br>
<A href="#Synopsis">Synopsis</A><br>
<A href="#functions">Free Functions</A><br>
<A href="#example">Example</A><br>
<h2><a name="Introduction">Introduction</a></h2>
<p>Consistent use of <a href="shared_ptr.htm"><code>shared_ptr</code></a>
can eliminate the need to use an explicit <code>delete</code>,
but alone it provides no support in avoiding explicit <code>new</code>.
There have been repeated requests from users for a factory function that creates
an object of a given type and returns a <code>shared_ptr</code> to it.
Besides convenience and style, such a function is also exception safe and
considerably faster because it can use a single allocation for both the object
and its corresponding control block, eliminating a significant portion of
<code>shared_ptr</code>'s construction overhead.
This eliminates one of the major efficiency complaints about <code>shared_ptr</code>.
</p>
<p>The header file &lt;boost/make_shared.hpp&gt; provides a family of overloaded function templates,
<code>make_shared</code> and <code>allocate_shared</code>, to address this need.
<code>make_shared</code> uses the global operator <code>new</code> to allocate memory,
whereas <code>allocate_shared</code> uses an user-supplied allocator, allowing finer control.</p>
<p>
The rationale for choosing the name <code>make_shared</code> is that the expression
<code>make_shared&lt;Widget&gt;()</code> can be read aloud and conveys the intended meaning.</p>
<h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost {
template&lt;typename T&gt; class shared_ptr;
template&lt;typename T&gt;
shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>();
template&lt;typename T, typename A&gt;
shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( A const &amp; );
#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // C++0x prototypes
template&lt;typename T, typename... Args&gt;
shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>( Args &amp;&amp; ... args );
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( A const &amp; a, Args &amp;&amp; ... args );
#else // no C++0X support
template&lt;typename T, typename Arg1 &gt;
shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>( Arg1 const &amp; arg1 );
template&lt;typename T, typename Arg1, typename Arg2 &gt;
shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>( Arg1 const &amp; arg1, Arg2 const &amp; arg2 );
// ...
template&lt;typename T, typename Arg1, typename Arg2, ..., typename ArgN &gt;
shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>( Arg1 const &amp; arg1, Arg2 const &amp; arg2, ..., ArgN const &amp; argN );
template&lt;typename T, typename A, typename Arg1 &gt;
shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( A const &amp; a, Arg1 const &amp; arg1 );
template&lt;typename T, typename A, typename Arg1, typename Arg2 &gt;
shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( Arg1 const &amp; arg1, Arg2 const &amp; arg2 );
// ...
template&lt;typename T, typename A, typename Arg1, typename Arg2, ..., typename ArgN &gt;
shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( A const &amp; a, Arg1 const &amp; arg1, Arg2 const &amp; arg2, ..., ArgN const &amp; argN );
#endif
}</pre>
<h2><a name="functions">Free Functions</a></h2>
<pre>template&lt;class T, class... Args&gt;
shared_ptr&lt;T&gt; make_shared( Args &amp;&amp; ... args );
template&lt;class T, class A, class... Args&gt;
shared_ptr&lt;T&gt; allocate_shared( A const &amp; a, Args &amp;&amp; ... args );</pre>
<blockquote>
<p><b>Requires:</b> The expression <code>new( pv ) T( std::forward&lt;Args&gt;(args)... )</code>,
where <code>pv</code> is a <code>void*</code> pointing to storage suitable
to hold an object of type <code>T</code>,
shall be well-formed. <code>A</code> shall be an <em>Allocator</em>,
as described in section 20.1.5 (<strong>Allocator requirements</strong>) of the C++ Standard.
The copy constructor and destructor of <code>A</code> shall not throw.</p>
<p><b>Effects:</b> Allocates memory suitable for an object of type <code>T</code>
and constructs an object in it via the placement new expression <code>new( pv ) T()</code>
or <code>new( pv ) T( std::forward&lt;Args&gt;(args)... )</code>.
<code>allocate_shared</code> uses a copy of <code>a</code> to allocate memory.
If an exception is thrown, has no effect.</p>
<p><b>Returns:</b> A <code>shared_ptr</code> instance that stores and owns the address
of the newly constructed object of type <code>T</code>.</p>
<p><b>Postconditions:</b> <code>get() != 0 &amp;&amp; use_count() == 1</code>.</p>
<p><b>Throws:</b> <code>bad_alloc</code>, or an exception thrown from <code>A::allocate</code>
or the constructor of <code>T</code>.</p>
<p><b>Notes:</b> This implementation allocates the memory required for the
returned <code>shared_ptr</code> and an object of type <code>T</code> in a single
allocation. This provides efficiency equivalent to an intrusive smart pointer.</p>
<p>The prototypes shown above are used if your compiler supports rvalue references
and variadic templates. They perfectly forward the <code>args</code> parameters to
the constructors of <code>T</code>.</p>
<p>Otherwise, the implementation will fall back on
forwarding the arguments to the constructors of <code>T</code> as const references.
If you need to pass a non-const reference to a constructor of <code>T</code>,
you may do so by wrapping the parameter in a call to <code>boost::ref</code>.
In addition, you will be
limited to a maximum of 9 arguments (not counting the allocator argument of
allocate_shared).</p>
</blockquote>
<h2><a name="example">Example</a></h2>
<pre>boost::shared_ptr&lt;std::string&gt; x = boost::make_shared&lt;std::string&gt;("hello, world!");
std::cout << *x;</pre>
<hr>
<p>$Date$</p>
<p><small>Copyright 2008 Peter Dimov. Copyright 2008 Frank Mori Hess.
Distributed under the Boost Software License,
Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A>
or copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

View File

@ -1,393 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>allocate_shared and make_shared for arrays</title>
</head>
<body>
<h1>allocate_shared and make_shared for arrays</h1>
<div id="navigation">
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#synopsis">Synopsis</a></li>
<li><a href="#requirements">Common Requirements</a></li>
<li><a href="#functions">Free Functions</a></li>
<li><a href="#history">History</a></li>
<li><a href="#references">References</a></li>
</ul>
</div>
<div id="introduction">
<h2>Introduction</h2>
<p>
Originally the Boost function templates <code>allocate_shared</code> and
<code>make_shared</code> were for efficient allocation of shared scalar
objects only. There was a need to have efficient allocation of shared
arrays. One criticism of class template <code>shared_array</code>
was always the lack of a utility like <code>make_shared</code> that
uses only a single allocation.
</p>
<p>
The header files &lt;boost/smart_ptr/allocate_shared_array.hpp&gt; and
&lt;boost/smart_ptr/make_shared_array.hpp&gt; provide function
templates, overloads of <code>allocate_shared</code> and
<code>make_shared</code> for array types, to address this need.
<code>allocate_shared</code> uses a user-supplied allocator for
allocation, while <code>make_shared</code> uses
<code>allocate_shared</code> with the Default Allocator.
</p>
</div>
<div id="synopsis">
<h2>Synopsis</h2>
<div>
<h3>Header &lt;boost/smart_ptr/allocate_shared_array.hpp&gt;</h3>
<code>namespace boost {</code>
<blockquote>
<code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
<a href="#functions">allocate_shared</a>(const A&amp; a,
std::size_t n);</code>
</blockquote>
<blockquote>
<code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
<a href="#functions">allocate_shared</a>(const A&amp; a);</code>
</blockquote>
<blockquote>
<code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
<a href="#functions">allocate_shared</a>(const A&amp; a, std::size_t n,
const <em>E</em>&amp; v);</code>
</blockquote>
<blockquote>
<code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
<a href="#functions">allocate_shared</a>(const A&amp; a,
const <em>E</em>&amp; v);</code>
</blockquote>
<blockquote>
<code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
<a href="#functions">allocate_shared_noinit</a>(const A&amp; a,
std::size_t n);</code>
</blockquote>
<blockquote>
<code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
<a href="#functions">allocate_shared_noinit</a>(const A&amp; a);</code>
</blockquote>
<code>}</code>
</div>
<div>
<h3>Header &lt;boost/smart_ptr/make_shared_array.hpp&gt;</h3>
<code>namespace boost {</code>
<blockquote>
<code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
<a href="#functions">make_shared</a>(std::size_t n);</code>
</blockquote>
<blockquote>
<code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
<a href="#functions">make_shared</a>();</code>
</blockquote>
<blockquote>
<code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
<a href="#functions">make_shared</a>(std::size_t n,
const <em>E</em>&amp; v);</code>
</blockquote>
<blockquote>
<code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
<a href="#functions">make_shared</a>(const <em>E</em>&amp; v);</code>
</blockquote>
<blockquote>
<code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
<a href="#functions">make_shared_noinit</a>(std::size_t n);</code>
</blockquote>
<blockquote>
<code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
<a href="#functions">make_shared_noinit</a>();</code>
</blockquote>
<code>}</code>
</div>
</div>
<div id="requirements">
<h2>Common Requirements</h2>
<h3><code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
allocate_shared(const A&amp; a, <em>args</em>);</code></h3>
<dl>
<dt><strong>Requires:</strong></dt>
<dd><code>T</code> is of the form <code>E[N]</code> or
<code>E[]</code>. <code>A</code> shall be an <em>Allocator</em>, as
described in section 17.6.3.5 [Allocator requirements] of the C++
Standard. The copy constructor and destructor of <code>A</code> shall
not throw exceptions.</dd>
<dt><strong>Effects:</strong></dt>
<dd>Allocates storage for an object of type <code>E</code> (or
<code>E[size]</code> when <code>T</code> is <code>E[]</code>, where
<code>size</code> is determined from <code>args</code> as specified by
the concrete overload). A copy of the allocator is used to allocate
storage. The storage is initialized as specified by the concrete
overload. If an exception is thrown, the functions have no effect.</dd>
<dt><strong>Returns:</strong></dt>
<dd>A <code>shared_ptr</code> instance that stores and owns the address
of the newly allocated and constructed object.</dd>
<dt><strong>Postconditions:</strong></dt>
<dd><code>r.get() != 0</code> and <code>r.use_count() == 1</code>,
where <code>r</code> is the return value.</dd>
<dt><strong>Throws:</strong></dt>
<dd>An exception thrown from <code>A::allocate()</code>, or from the
initialization of the object.</dd>
<dt><strong>Remarks:</strong></dt>
<dd>
<ul>
<li>This implementation performs no more than one memory allocation.
This provides efficiency to equivalent to an intrusive smart
pointer.</li>
<li>When an object of an array type <code>T</code> is specified to be
initialized to a value of the same type <code>v</code>, this shall be
interpreted to mean that each array element of the object is initialized
to the corresponding element from <code>v</code>.</li>
<li>When an object of an array type <code>T</code> is specified to be
value-initialized, this shall be interpreted to mean that each array
element of the object is value-initialized.</li>
<li>Array elements are initialized in ascending order of their
addresses.</li>
<li>When a subobject of a scalar type <code>S</code> is specified to
be initialized to a value <code>v</code>, <code>allocate_shared</code>
shall perform this initialization via the expression
<code>std::allocator_traits&lt;A&gt;::construct(b, p, v)</code>, where
<code>p</code> points to storage suitable to hold an object of type
<code>S</code> and <code>b</code> of is a copy of the allocator
<code>a</code> passed to <code>allocate_shared</code> such that its
<code>value_type</code> is <code>S</code>.</li>
<li>When a subobject of scalar type <code>S</code> is specified to be
value-initialized, <code>allocate_shared</code> shall perform this
initialization via the expression
<code>std::allocator_traits&lt;A&gt;::construct(b, p)</code>, where
<code>p</code> points to storage suitable to hold an object
of type <code>S</code> and <code>b</code> is a copy of the allocator
<code>a</code> passed to <code>allocate_shared</code> such that its
<code>value_type</code> is <code>S</code>.</li>
<li>When a subobject of scalar type <code>S</code> is specified to be
default-initialized, <code>allocate_shared_noinit</code> shall perform
this initialization via the expression <code>::new(p) S</code>, where
<code>p</code> has type <code>void*</code> and points to storage
suitable to hold an object of type <code>S</code>.</li>
<li>When the lifetime of the object managed by the return value ends,
or when the initialization of an array element throws an exception,
the initialized elements should be destroyed in the reverse order
of their construction.</li>
</ul>
</dd>
<dt><strong>Notes:</strong></dt>
<dd>These functions will typically allocate more memory than the size of
<code>sizeof(E)</code> to allow for internal bookkeeping structures such
as the reference counts.</dd>
</dl>
</div>
<div id="functions">
<h2>Free Functions</h2>
<div>
<h3><code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
allocate_shared(const A&amp; a, std::size_t n);</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd>A <code>shared_ptr</code> to a value-initialized object of type
<code>E[size]</code>.</dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is of the form <code>E[]</code>.</dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::allocate_shared&lt;int[]<!--
-->&gt;(std::allocator&lt;int&gt;(), 8);</code></dd>
</dl>
</div>
<div>
<h3><code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
allocate_shared(const A&amp; a);</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd>A <code>shared_ptr</code> to a value-initialized object of type
<code>E[N]</code>.</dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is of the form <code>E[N]</code>.</dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::allocate_shared&lt;int[8]<!--
-->&gt;(std::allocator&lt;int&gt;());</code></dd>
</dl>
</div>
<div>
<h3><code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
allocate_shared(const A&amp; a, std::size_t n,
const <em>E</em>&amp; v);</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd>A <code>shared_ptr</code> to an object of type
<code>E[size]</code>, where each array element of type <code>E</code> is
initialized to <code>v</code>.</dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is of the form <code>E[]</code>.</dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::allocate_shared&lt;double[]<!--
-->&gt;(std::allocator&lt;double&gt;(), 8, 1.0);</code></dd>
</dl>
</div>
<div>
<h3><code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
allocate_shared(const A&amp; a, const <em>E</em>&amp; v);</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd>A <code>shared_ptr</code> to an object of type <code>E[N]</code>,
where each array element of type <code>E</code> is initialized to
<code>v</code>.</dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is of the form <code>E[N]</code>.</dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::allocate_shared&lt;double[8]<!--
-->&gt;(std::allocator&lt;double&gt;(), 1.0);</code></dd>
</dl>
</div>
<div>
<h3><code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
allocate_shared_noinit(const A&amp; a, std::size_t n);</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd>A <code>shared_ptr</code> to a default-initialized object of type
<code>E[size]</code>.</dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is of the form <code>E[]</code>.</dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::allocate_shared_noinit&lt;int[]<!--
-->&gt;(std::allocator&lt;int&gt;(), 8);</code></dd>
</dl>
</div>
<div>
<h3><code>template&lt;class T, class A&gt;<br>shared_ptr&lt;T&gt;
allocate_shared_noinit(const A&amp; a);</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd>A <code>shared_ptr</code> to a default-initialized object of type
<code>E[N]</code>.</dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is of the form <code>E[N]</code>.</dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::allocate_shared_noinit&lt;int[8]<!--
-->&gt;(std::allocator&lt;int&gt;());</code></dd>
</dl>
</div>
<div>
<h3><code>template&lt;class T&gt;<br>shared_ptr&lt;T&gt;
make_shared(std::size_t n);</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd><code>allocate_shared&lt;T&gt;(std::allocator&lt;<em>S<!--
--></em>&gt;(), n);</code></dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is of the form <code>E[]</code>.</dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::make_shared&lt;int[]&gt;(8);</code></dd>
</dl>
</div>
<div>
<h3><code>template&lt;class T&gt;<br>shared_ptr&lt;T&gt;
make_shared();</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd><code>allocate_shared&lt;T&gt;(std::allocator&lt;<em>S<!--
--></em>&gt;());</code></dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is of the form <code>E[N]</code>.</dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::make_shared&lt;int[8]&gt;();</code></dd>
</dl>
</div>
<div>
<h3><code>template&lt;class T&gt;<br>shared_ptr&lt;T&gt;
make_shared(std::size_t n, const <em>E</em>&amp; v);</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd><code>allocate_shared&lt;T&gt;(std::allocator&lt;<em>S<!--
--></em>&gt;(), n, v);</code></dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is of the form <code>E[]</code>.</dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::make_shared&lt;double[]&gt;(8, 1.0);</code></dd>
</dl>
</div>
<div>
<h3><code>template&lt;class T&gt;<br>shared_ptr&lt;T&gt;
make_shared(const <em>E</em>&amp; v);</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd><code>allocate_shared&lt;T&gt;(std::allocator&lt;<em>S<!--
--></em>&gt;(), v);</code></dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is of the form <code>E[N].</code></dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::make_shared&lt;double[8]&gt;(1.0);</code></dd></dl>
</div>
<div>
<h3><code>template&lt;class T&gt;<br>shared_ptr&lt;T&gt;
make_shared_noinit(std::size_t n);</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd><code>allocate_shared_noinit&lt;T&gt;(std::allocator&lt;<em>S<!--
--></em>&gt;(), n);</code></dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is of the form <code>E[]</code>.</dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::make_shared_noinit&lt;int[]&gt;(8);</code></dd>
</dl>
</div>
<div>
<h3><code>template&lt;class T&gt;<br>shared_ptr&lt;T&gt;
make_shared_noinit();</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd><code>allocate_shared_noinit&lt;T&gt;(std::allocator&lt;<em>S<!--
--></em>&gt;());</code></dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is of the form <code>E[N]</code>.</dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::make_shared_noinit&lt;int[8]&gt;();</code></dd>
</dl>
</div>
</div>
<div id="history">
<h2>History</h2>
<dl>
<dt><strong>Boost 1.64</strong></dt>
<dd>Glen Fernandes rewrote allocate_shared and make_shared for a more
optimal and more maintainable implementation.</dd>
<dt><strong>Boost 1.56</strong></dt>
<dd>Glen Fernandes updated overloads of make_shared and allocate_shared
to conform to the specification in C++ standard paper
<a href="#N3870">N3870</a>, including resolving C++ standard library
defect report <a href="#dr2070">DR 2070</a>.</dd>
<dt><strong>Boost 1.53</strong></dt>
<dd>Glen Fernandes contributed implementations of make_shared and
allocate_shared for arrays.</dd>
</dl>
</div>
<div id="references">
<h2>References</h2>
<ol>
<li id="N3870"><strong>N3870</strong>, <a href=
"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3870.html">
Extending make_shared to Support Arrays, Revision 1</a>, Peter Dimov
&amp; Glen Fernandes, January, 2014.</li>
<li id="dr2070"><strong>DR 2070</strong>,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html">
allocate_shared should use allocator_traits&lt;A&gt;::construct</a>,
Jonathan Wakely, July, 2011.</li>
</ol>
</div>
<hr>
Copyright 2012-2017 Glen Fernandes. Distributed under the
<a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License,
Version 1.0</a>.
</body>
</html>

View File

@ -1,184 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>make_unique</title>
</head>
<body>
<h1>make_unique</h1>
<div id="navigation">
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#synopsis">Synopsis</a></li>
<li><a href="#requirements">Common Requirements</a></li>
<li><a href="#functions">Free Functions</a></li>
<li><a href="#history">History</a></li>
</ul>
</div>
<div id="introduction">
<h2>Introduction</h2>
<p>
The header file &lt;boost/make_unique.hpp&gt; provides overloads of
function template <code>make_unique</code> for convenient creation of
<code>std::unique_ptr</code> objects.
</p>
</div>
<div id="synopsis">
<h2>Synopsis</h2>
<div>
<h3>Header &lt;boost/smart_ptr/make_unique.hpp&gt;</h3>
<code>namespace boost {</code>
<blockquote>
<code>template&lt;class T&gt;<br>std::unique_ptr&lt;T&gt;
<a href="#functions">make_unique</a>();</code>
</blockquote>
<blockquote>
<code>template&lt;class T, class... Args&gt;<br>std::unique_ptr&lt;T&gt;
<a href="#functions">make_unique</a>(Args&amp;&amp;... args);</code>
</blockquote>
<blockquote>
<code>template&lt;class T&gt;<br>std::unique_ptr&lt;T&gt;
<a href="#functions">make_unique</a>(<em>T</em>&amp;&amp; value);</code>
</blockquote>
<blockquote>
<code>template&lt;class T&gt;<br>std::unique_ptr&lt;T&gt;
<a href="#functions">make_unique</a>(std::size_t size);</code>
</blockquote>
<blockquote>
<code>template&lt;class T&gt;<br>std::unique_ptr&lt;T&gt;
<a href="#functions">make_unique_noinit</a>();</code>
</blockquote>
<blockquote>
<code>template&lt;class T&gt;<br>std::unique_ptr&lt;T&gt;
<a href="#functions">make_unique_noinit</a>(std::size_t size);</code>
</blockquote>
<code>}</code>
</div>
</div>
<div id="requirements">
<h2>Common Requirements</h2>
<h3><code>template&lt;class T, <em>Args</em>&gt;<br>
std::unique_ptr&lt;T&gt; make_unique(<em>args</em>);</code></h3>
<dl>
<dt><strong>Effects:</strong></dt>
<dd>Allocates storage for an object of type <code>T</code> (or
<code>E[size]</code> when <code>T</code> is <code>E[]</code>, where
<code>size</code> is determined from <code>args</code> as specified by
the concrete overload). The storage is initialized from
<code>args</code> as specified by the concrete overload. If an exception
is thrown, the functions have no effect.</dd>
<dt><strong>Returns:</strong></dt>
<dd>A <code>std::unique_ptr</code> instance that stores and owns the
address of the newly allocated and constructed object.</dd>
<dt><strong>Postconditions:</strong></dt>
<dd><code>r.get() != 0</code>, where <code>r</code> is the return
value.</dd>
<dt><strong>Throws:</strong></dt>
<dd><code>std::bad_alloc</code>, or an exception thrown from the
initialization of the object.</dd>
<dt><strong>Remarks:</strong></dt>
<dd>
<ul>
<li>When an object of a scalar type T is specified to be initialized to
a value <code>value</code>, or to <code>T(args...)</code>, where
<code>args...</code> is a list of constructor arguments,
<code>make_unique</code> shall perform this initialization via the
expression <code>new T(value)</code> or <code>new T(args...)</code>
respectively.</li>
<li>When an object of type <code>T</code> is specified to be
value-initialized, <code>make_unique</code> shall perform this
initialization via the expression <code>new T()</code>.</li>
<li>When an object of type <code>T</code> is specified to be
default-initialized, <code>make_unique_noinit</code> shall perform this
initialization via the expression <code>new T</code>.</li>
</ul>
</dd>
</dl>
</div>
<div id="functions">
<h2>Free functions</h2>
<div>
<h3><code>template&lt;class T, class... Args&gt;<br>
std::unique_ptr&lt;T&gt;
make_unique(Args&amp;&amp;... args);</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd>A <code>std::unique_ptr</code> to an object of type <code>T</code>,
initialized to <code>std::forward&lt;Args&gt;(args)...</code>.</dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is not an array type.</dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::make_unique&lt;double&gt;(1.0);</code></dd>
</dl>
</div>
<div>
<h3><code>template&lt;class T&gt;<br>std::unique_ptr&lt;T&gt;
make_unique(<em>T</em>&amp;&amp; value);</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd>A <code>std::unique_ptr</code> to an object of type <code>T</code>,
initialized to <code>std::move(value)</code>.</dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is not an array type.</dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::make_unique&lt;point&gt;({1.0, -1.0});</code></dd></dl>
</div>
<div>
<h3><code>template&lt;class T&gt;<br>std::unique_ptr&lt;T&gt;
make_unique(std::size_t size);</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd>A <code>std::unique_ptr</code> to a value-initialized object of type
<code>E[size]</code>.</dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is of the form <code>E[]</code>.</dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::make_unique&lt;int[]&gt;(8);</code></dd>
</dl>
</div>
<div>
<h3><code>template&lt;class T&gt;<br>std::unique_ptr&lt;T&gt;
make_unique_noinit();</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd>A <code>std::unique_ptr</code> to a default-initialized object of
type <code>T</code>.</dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is not an array type.</dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::make_unique_noinit&lt;std::tm&gt;();</code></dd>
</dl>
</div>
<div>
<h3><code>template&lt;class T&gt;<br>std::unique_ptr&lt;T&gt;
make_unique_noinit(std::size_t size);</code></h3>
<dl>
<dt><strong>Returns:</strong></dt>
<dd>A <code>std::unique_ptr</code> to a default-initialized object of
type <code>E[size]</code>.</dd>
<dt><strong>Remarks:</strong></dt>
<dd>This overload shall only participate in overload resolution when
<code>T</code> is of the form <code>E[]</code>.</dd>
<dt><strong>Example:</strong></dt>
<dd><code>boost::make_unique_noinit&lt;char[]&gt;(64);</code></dd>
</dl>
</div>
</div>
<div id="history">
<h2>History</h2>
<dl>
<dt><strong>Boost 1.56</strong></dt>
<dd>Glen Fernandes contributed implementations of make_unique for
scalars and arrays</dd>
</dl>
</div>
<hr>
Copyright 2012-2014 Glen Fernandes. Distributed under the
<a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License,
Version 1.0</a>.
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -1,183 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>pointer_cast</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0" />pointer_cast</h1>
<p>The pointer cast functions (<code>boost::static_pointer_cast</code> <code>boost::dynamic_pointer_cast</code>
<code>boost::reinterpret_pointer_cast</code> <code>boost::const_pointer_cast</code>)
provide a way to write generic pointer castings for raw pointers, <code>std::shared_ptr</code> and <code>std::unique_ptr</code>. The functions
are defined in <cite><a href="../../boost/pointer_cast.hpp">boost/pointer_cast.hpp</a>.</cite></p>
<p>There is test/example code in <cite><a href="test/pointer_cast_test.cpp">pointer_cast_test.cpp</a></cite>.</p>
<h2><a name="rationale">Rationale</a></h2>
<P>Boost smart pointers usually overload those functions to provide a mechanism to
emulate pointers casts. For example, <code>boost::shared_ptr&lt;...&gt;</code> implements
a static pointer cast this way:</P>
<pre>
template&lt;class T, class U&gt;
shared_ptr&lt;T&gt; static_pointer_cast(shared_ptr&lt;U&gt; const &amp;r);
</pre>
<p>Pointer cast functions from <cite><A href="../../boost/pointer_cast.hpp">boost/pointer_cast.hpp</A></CITE>
are overloads of <code>boost::static_pointer_cast</code>, <code>boost::dynamic_pointer_cast</code>,
<code>boost::reinterpret_pointer_cast</code> and <code>boost::const_pointer_cast</code>
for raw pointers, <code>std::shared_ptr</code> and <code>std::unique_ptr</code>. This way when developing
pointer type independent classes, for example, memory managers or shared memory compatible classes, the same
code can be used for raw and smart pointers.</p>
<h2><a name="synopsis">Synopsis</a></h2>
<blockquote>
<pre>
namespace boost {
template&lt;class T, class U&gt;
inline T* static_pointer_cast(U *ptr)
{ return static_cast&lt;T*&gt;(ptr); }
template&lt;class T, class U&gt;
inline T* dynamic_pointer_cast(U *ptr)
{ return dynamic_cast&lt;T*&gt;(ptr); }
template&lt;class T, class U&gt;
inline T* const_pointer_cast(U *ptr)
{ return const_cast&lt;T*&gt;(ptr); }
template&lt;class T, class U&gt;
inline T* reinterpret_pointer_cast(U *ptr)
{ return reinterpret_cast&lt;T*&gt;(ptr); }
template&lt;class T, class U&gt;
inline std::shared_ptr&lt;T&gt; static_pointer_cast(std::shared_ptr&lt;U&gt; const&amp; r);
template&lt;class T, class U&gt;
inline std::shared_ptr&lt;T&gt; dynamic_pointer_cast(std::shared_ptr&lt;U&gt; const&amp; r);
template&lt;class T, class U&gt;
inline std::shared_ptr&lt;T&gt; const_pointer_cast(std::shared_ptr&lt;U&gt; const&amp; r);
template&lt;class T, class U&gt;
inline std::shared_ptr&lt;T&gt; reinterpret_pointer_cast(std::shared_ptr&lt;U&gt; const&amp; r);
template&lt;class T, class U&gt;
inline std::unique_ptr&lt;T&gt; static_pointer_cast(std::unique_ptr&lt;U&gt;&amp;&amp; r);
template&lt;class T, class U&gt;
inline std::unique_ptr&lt;T&gt; dynamic_pointer_cast(std::unique_ptr&lt;U&gt;&amp;&amp; r);
template&lt;class T, class U&gt;
inline std::unique_ptr&lt;T&gt; const_pointer_cast(std::unique_ptr&lt;U&gt;&amp;&amp; r);
template&lt;class T, class U&gt;
inline std::unique_ptr&lt;T&gt; reinterpret_pointer_cast(std::unique_ptr&lt;U&gt;&amp;&amp; r);
} // namespace boost
</pre>
</blockquote>
<p>As you can see from the above synopsis, the pointer cast functions for raw pointers are just
wrappers around standard C++ cast operators.</p>
<p>The pointer casts for <code>std::shared_ptr</code> are aliases of the corresponding standard
functions with the same names and equivalent to <a href="shared_ptr.htm#static_pointer_cast">the
functions taking <code>boost::shared_ptr</code></a>.</p>
<p>The pointer casts for <code>std::unique_ptr</code> are documented below.</p>
<h3 id="static_pointer_cast">static_pointer_cast</h3>
<pre>template&lt;class T, class U&gt;
unique_ptr&lt;T&gt; static_pointer_cast(unique_ptr&lt;U&gt;&amp;&amp; r); // never throws</pre>
<blockquote>
<p><b>Requires:</b> The expression <code>static_cast&lt;T*&gt;( (U*)0 )</code>
must be well-formed.</p>
<p><b>Returns:</b> <code>unique_ptr&lt;T&gt;( static_cast&lt;typename unique_ptr&lt;T&gt;::element_type*&gt;(r.release()) )</code>.</p>
<p><b>Throws:</b> nothing.</p>
<p><b>Notes:</b> the seemingly equivalent expression
<code>unique_ptr&lt;T&gt;(static_cast&lt;T*&gt;(r.get()))</code>
will eventually result in undefined behavior, attempting to delete the same
object twice.</p>
</blockquote>
<h3 id="const_pointer_cast">const_pointer_cast</h3>
<pre>template&lt;class T, class U&gt;
unique_ptr&lt;T&gt; const_pointer_cast(unique_ptr&lt;U&gt;&amp;&amp; r); // never throws</pre>
<blockquote>
<p><b>Requires:</b> The expression <code>const_cast&lt;T*&gt;( (U*)0 )</code>
must be well-formed.</p>
<p><b>Returns:</b> <code>unique_ptr&lt;T&gt;( const_cast&lt;typename unique_ptr&lt;T&gt;::element_type*&gt;(r.release()) )</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3 id="dynamic_pointer_cast">dynamic_pointer_cast</h3>
<pre>template&lt;class T, class U&gt;
unique_ptr&lt;T&gt; dynamic_pointer_cast(unique_ptr&lt;U&gt;&amp;&amp; r);</pre>
<blockquote>
<p><b>Requires:</b> The expression <code>dynamic_cast&lt;T*&gt;( (U*)0 )</code>
must be well-formed. <code>T</code> must have a virtual destructor.</p>
<p><b>Returns:</b></p>
<ul>
<li>
When <code>dynamic_cast&lt;typename unique_ptr&lt;T&gt;::element_type*&gt;(r.get())</code> returns a nonzero value,
<code>unique_ptr&lt;T&gt;(dynamic_cast&lt;typename unique_ptr&lt;T&gt;::element_type*&gt;(r.release()))</code>;</li>
<li>
Otherwise, <code>unique_ptr&lt;T&gt;()</code>.</li></ul>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3 id="reinterpret_pointer_cast">reinterpret_pointer_cast</h3>
<pre>template&lt;class T, class U&gt;
unique_ptr&lt;T&gt; reinterpret_pointer_cast(unique_ptr&lt;U&gt;&amp;&amp; r); // never throws</pre>
<blockquote>
<p><b>Requires:</b> The expression <code>reinterpret_cast&lt;T*&gt;( (U*)0 )</code>
must be well-formed.</p>
<p><b>Returns:</b> <code>unique_ptr&lt;T&gt;( reinterpret_cast&lt;typename unique_ptr&lt;T&gt;::element_type*&gt;(r.release()) )</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h2><a name="example">Example</a></h2>
<blockquote>
<pre>
#include &lt;boost/pointer_cast.hpp&gt;
#include &lt;boost/shared_ptr.hpp&gt;
class base
{
public:
virtual ~base()
{
}
};
class derived: public base
{
};
template &lt;class BasePtr&gt;
void check_if_it_is_derived(const BasePtr &amp;ptr)
{
assert(boost::dynamic_pointer_cast&lt;derived&gt;(ptr) != 0);
}
int main()
{
<em>// Create a raw and a shared_ptr</em>
base *ptr = new derived;
boost::shared_ptr&lt;base&gt; sptr(new derived);
<em>// Check that base pointer points actually to derived class</em>
check_if_it_is_derived(ptr);
check_if_it_is_derived(sptr);
<em>// Ok!</em>
delete ptr;
return 0;
}</pre>
</blockquote>
<p>The example demonstrates how the generic pointer casts help us create pointer
independent code.</p>
<hr />
<p>Copyright 2005 Ion Gazta<74>aga. Use, modification, and distribution are subject to
the Boost Software License, Version 1.0. (See accompanying file <a href="../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or a copy at &lt;<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>&gt;.)</p>
</body>
</html>

View File

@ -1,108 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>pointer_to_other</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0">pointer_to_other</h1>
<p>
The pointer to other utility provides a way, given a source pointer type,
to obtain a pointer of the same type to another pointee type. The utility is
defined in <cite><a href="../../boost/pointer_to_other.hpp">boost/pointer_to_other.hpp</a>.</cite></p>
<p>There is test/example code in <cite><a href="test/pointer_to_other_test.cpp">pointer_to_other_test.cpp</a></cite>.</p>
<h2><a name="contents">Contents</a></h2>
<ul>
<li>
<a href="#rationale">Rationale</a>
<li>
<a href="#synopsis">Synopsis</a>
<li>
<a href="#example">Example</a></li>
</ul>
<h2><a name="rationale">Rationale</a></h2>
<p>When building pointer independent classes, like memory managers, allocators, or
containers, there is often a need to define pointers generically, so that if a
template parameter represents a pointer (for example, a raw or smart pointer to
an int), we can define another pointer of the same type to another pointee (a
raw or smart pointer to a float.)</p>
<pre>template &lt;class IntPtr&gt;
class FloatPointerHolder
{
<em>// Let's define a pointer to a float</em>
typedef typename boost::pointer_to_other
&lt;IntPtr, float&gt;::type float_ptr_t;
float_ptr_t float_ptr;
};</pre>
<h2><a name="synopsis">Synopsis</a></h2>
<pre>
namespace boost {
template&lt;class T, class U&gt;
struct pointer_to_other;
template&lt;class T, class U, template &lt;class&gt; class Sp&gt;
struct pointer_to_other&lt; Sp&lt;T&gt;, U &gt;
{
typedef Sp&lt;U&gt; type;
};
template&lt;class T, class T2, class U,
template &lt;class, class&gt; class Sp&gt;
struct pointer_to_other&lt; Sp&lt;T, T2&gt;, U &gt;
{
typedef Sp&lt;U, T2&gt; type;
};
template&lt;class T, class T2, class T3, class U,
template &lt;class, class, class&gt; class Sp&gt;
struct pointer_to_other&lt; Sp&lt;T, T2, T3&gt;, U &gt;
{
typedef Sp&lt;U, T2, T3&gt; type;
};
template&lt;class T, class U&gt;
struct pointer_to_other&lt; T*, U &gt;
{
typedef U* type;
};
} <em>// namespace boost</em></pre>
<p>If these definitions are not correct for a specific smart pointer, we can define
a specialization of pointer_to_other.</p>
<h2><a name="example">Example</a></h2>
<pre><em>// Let's define a memory allocator that can
// work with raw and smart pointers</em>
#include &lt;boost/pointer_to_other.hpp&gt;
template &lt;class VoidPtr&gt;
class memory_allocator
{<em>
// Predefine a memory_block </em>
struct block;<em>
// Define a pointer to a memory_block from a void pointer
// If VoidPtr is void *, block_ptr_t is block*
// If VoidPtr is smart_ptr&lt;void&gt;, block_ptr_t is smart_ptr&lt;block&gt;</em>
typedef typename boost::pointer_to_other
&lt;VoidPtr, block&gt;::type block_ptr_t;
struct block
{
std::size_t size;
block_ptr_t next_block;
};
block_ptr_t free_blocks;
};</pre>
<p>As we can see, using pointer_to_other we can create pointer independent code.</p>
<hr>
<p>$Date$</p>
<p><small>Copyright 2005, 2006 Ion Gazta<74>aga and Peter Dimov. Use, modification,
and distribution are subject to the Boost Software License, Version 1.0.<br>
(See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a
copy at &lt; <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>&gt;.)</small></p>
</body>
</html>

View File

@ -1,115 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>scoped_array</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0">scoped_array class template</h1>
<p>The <b>scoped_array</b> class template stores a pointer to a dynamically
allocated array. (Dynamically allocated arrays are allocated with the C++ <b>new[]</b>
expression.) The array pointed to is guaranteed to be deleted, either on
destruction of the <b>scoped_array</b>, or via an explicit <b>reset</b>.</p>
<p>The <b>scoped_array</b> template is a simple solution for simple needs. It
supplies a basic "resource acquisition is initialization" facility, without
shared-ownership or transfer-of-ownership semantics. Both its name and
enforcement of semantics (by being <a href="../utility/utility.htm#Class_noncopyable">
noncopyable</a>) signal its intent to retain ownership solely within the
current scope. Because it is <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>,
it is safer than <b>shared_array</b> for pointers which should not be copied.</p>
<p>Because <b>scoped_array</b> is so simple, in its usual implementation every
operation is as fast as a built-in array pointer and it has no more space
overhead that a built-in array pointer.</p>
<p>It cannot be used in C++ standard library containers. See <a href="shared_array.htm">
<b>shared_array</b></a> if <b>scoped_array</b> does not meet your needs.</p>
<p>It cannot correctly hold a pointer to a single object. See <a href="scoped_ptr.htm"><b>scoped_ptr</b></a>
for that usage.</p>
<p>A <b>std::vector</b> is an alternative to a <b>scoped_array</b> that is a bit
heavier duty but far more flexible. A <b>boost::array</b> is an alternative
that does not use dynamic allocation.</p>
<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>.</p>
<h2>Synopsis</h2>
<pre>namespace boost {
template&lt;class T&gt; class scoped_array : <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a> {
public:
typedef T <a href="#element_type">element_type</a>;
explicit <a href="#ctor">scoped_array</a>(T * p = 0); // never throws
<a href="#destructor">~scoped_array</a>(); // never throws
void <a href="#reset">reset</a>(T * p = 0); // never throws
T &amp; <a href="#operator[]">operator[]</a>(std::ptrdiff_t i) const; // never throws
T * <a href="#get">get</a>() const; // never throws
operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws
void <a href="#swap">swap</a>(scoped_array &amp; b); // never throws
};
template&lt;class T&gt; void <a href="#free-swap">swap</a>(scoped_array&lt;T&gt; &amp; a, scoped_array&lt;T&gt; &amp; b); // never throws
}</pre>
<h2>Members</h2>
<h3>
<a name="element_type">element_type</a></h3>
<pre>typedef T element_type;</pre>
<p>Provides the type of the stored pointer.</p>
<h3><a name="ctor">constructors</a></h3>
<pre>explicit scoped_array(T * p = 0); // never throws</pre>
<p>Constructs a <b>scoped_array</b>, storing a copy of <b>p</b>, which must have
been allocated via a C++ <b>new</b>[] expression or be 0. <b>T</b> is not
required be a complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">
common requirements</a>.</p>
<h3><a name="destructor">destructor</a></h3>
<pre>~scoped_array(); // never throws</pre>
<p>Deletes the array pointed to by the stored pointer. Note that <b>delete[]</b> on
a pointer with a value of 0 is harmless. The guarantee that this does not throw
exceptions depends on the requirement that the deleted array's objects'
destructors do not throw exceptions. See the smart pointer <a href="smart_ptr.htm#common_requirements">
common requirements</a>.</p>
<h3><a name="reset">reset</a></h3>
<pre>void reset(T * p = 0); // never throws</pre>
<p>
Deletes the array pointed to by the stored pointer and then stores a copy of p,
which must have been allocated via a C++ <b>new[]</b> expression or be 0. The
guarantee that this does not throw exceptions depends on the requirement that
the deleted array's objects' destructors do not throw exceptions. See the smart
pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
<h3><a name="operator[]">subscripting</a></h3>
<pre>T &amp; operator[](std::ptrdiff_t i) const; // never throws</pre>
<p>Returns a reference to element <b>i</b> of the array pointed to by the stored
pointer. Behavior is undefined and almost certainly undesirable if the stored
pointer is 0, or if <b>i</b> is less than 0 or is greater than or equal to the
number of elements in the array.</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="conversions">conversions</a></h3>
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
<p>Returns an unspecified value that, when used in boolean contexts, is equivalent
to <code>get() != 0</code>.</p>
<h3><a name="swap">swap</a></h3>
<pre>void swap(scoped_array &amp; 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="free-swap">swap</a></h3>
<pre>template&lt;class T&gt; void swap(scoped_array&lt;T&gt; &amp; a, scoped_array&lt;T&gt; &amp; 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>
<hr>
<p>$Date$</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

View File

@ -1,180 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>scoped_ptr</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0">scoped_ptr class template</h1>
<p>The <b>scoped_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, either on destruction of the <b>scoped_ptr</b>,
or via an explicit <b>reset</b>. See the <a href="#example">example</a>.</p>
<p>The <b>scoped_ptr</b> template is a simple solution for simple needs. It
supplies a basic "resource acquisition is initialization" facility, without
shared-ownership or transfer-of-ownership semantics. Both its name and
enforcement of semantics (by being <a href="../utility/utility.htm#Class_noncopyable">
noncopyable</a>) signal its intent to retain ownership solely within the
current scope. Because it is <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>,
it is safer than <b>shared_ptr</b> or <b>std::auto_ptr</b> for pointers which
should not be copied.</p>
<p>Because <b>scoped_ptr</b> is simple, in its usual implementation every operation
is as fast as for a built-in pointer and it has no more space overhead that a
built-in pointer.</p>
<p><STRONG>scoped_ptr</STRONG> cannot be used in C++ Standard Library containers.
Use <a href="shared_ptr.htm"><b>shared_ptr</b></a> if you need a smart pointer
that can.</p>
<p><STRONG>scoped_ptr</STRONG> cannot correctly hold a pointer to a dynamically
allocated array. See <a href="scoped_array.htm"><b>scoped_array</b></a> for
that usage.</p>
<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>.</p>
<h2>Synopsis</h2>
<pre>namespace boost {
template&lt;class T&gt; class scoped_ptr : <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a> {
public:
typedef T <a href="#element_type">element_type</a>;
explicit <a href="#constructors">scoped_ptr</a>(T * p = 0); // never throws
<a href="#destructor">~scoped_ptr</a>(); // never throws
void <a href="#reset">reset</a>(T * p = 0); // never throws
T &amp; <a href="#indirection">operator*</a>() const; // never throws
T * <a href="#indirection">operator-&gt;</a>() const; // never throws
T * <a href="#get">get</a>() const; // never throws
operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws
void <a href="#swap">swap</a>(scoped_ptr &amp; b); // never throws
};
template&lt;class T&gt; void <a href="#free-swap">swap</a>(scoped_ptr&lt;T&gt; &amp; a, scoped_ptr&lt;T&gt; &amp; b); // never throws
}</pre>
<h2>Members</h2>
<h3><a name="element_type">element_type</a></h3>
<pre>typedef T element_type;</pre>
<p>Provides the type of the stored pointer.</p>
<h3><a name="constructors">constructors</a></h3>
<pre>explicit scoped_ptr(T * p = 0); // never throws</pre>
<p>Constructs a <b>scoped_ptr</b>, storing a copy of <b>p</b>, which must have been
allocated via a C++ <b>new</b> expression or be 0. <b>T</b> is not required be
a complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common
requirements</a>.</p>
<h3><a name="destructor">destructor</a></h3>
<pre>~scoped_ptr(); // never throws</pre>
<p>Destroys the object pointed to by the stored pointer, if any, as if by using <tt>delete
this-&gt;get()</tt>.</p>
<P>
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="reset">reset</a></h3>
<pre>void reset(T * p = 0); // never throws</pre>
<p>
Deletes the object pointed to by the stored pointer and then stores a copy of
p, which must have been allocated via a C++ <b>new</b> expression or be 0. 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="indirection">indirection</a></h3>
<pre>T &amp; 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-&gt;() 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="conversions">conversions</a></h3>
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
<p>Returns an unspecified value that, when used in boolean contexts, is equivalent
to <code>get() != 0</code>.</p>
<h3><a name="swap">swap</a></h3>
<pre>void swap(scoped_ptr &amp; 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="free-swap">swap</a></h3>
<pre>template&lt;class T&gt; void swap(scoped_ptr&lt;T&gt; &amp; a, scoped_ptr&lt;T&gt; &amp; 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>
<h2><a name="example">Example</a></h2>
<p>Here's an example that uses <b>scoped_ptr</b>.</p>
<blockquote>
<pre>#include &lt;boost/scoped_ptr.hpp&gt;
#include &lt;iostream&gt;
struct Shoe { ~Shoe() { std::cout &lt;&lt; "Buckle my shoe\n"; } };
class MyClass {
boost::scoped_ptr&lt;int&gt; ptr;
public:
MyClass() : ptr(new int) { *ptr = 0; }
int add_one() { return ++*ptr; }
};
int main()
{
boost::scoped_ptr&lt;Shoe&gt; x(new Shoe);
MyClass my_instance;
std::cout &lt;&lt; my_instance.add_one() &lt;&lt; '\n';
std::cout &lt;&lt; my_instance.add_one() &lt;&lt; '\n';
}</pre>
</blockquote>
<p>The example program produces the beginning of a child's nursery rhyme:</p>
<blockquote>
<pre>1
2
Buckle my shoe</pre>
</blockquote>
<h2>Rationale</h2>
<p>The primary reason to use <b>scoped_ptr</b> rather than <b>auto_ptr</b> is to
let readers of your code know that you intend "resource acquisition is
initialization" to be applied only for the current scope, and have no intent to
transfer ownership.</p>
<p>A secondary reason to use <b>scoped_ptr</b> is to prevent a later maintenance
programmer from adding a function that transfers ownership by returning the <b>auto_ptr</b>,
because the maintenance programmer saw <b>auto_ptr</b>, and assumed ownership
could safely be transferred.</p>
<p>Think of <b>bool</b> vs <b>int</b>. We all know that under the covers <b>bool</b>
is usually just an <b>int</b>. Indeed, some argued against including <b>bool</b>
in the C++ standard because of that. But by coding <b>bool</b> rather than <b>int</b>,
you tell your readers what your intent is. Same with <b>scoped_ptr</b>; by
using it you are signaling intent.</p>
<p>It has been suggested that <b>scoped_ptr&lt;T&gt;</b> is equivalent to <b>std::auto_ptr&lt;T&gt;
const</b>. Ed Brey pointed out, however, that <b>reset</b> will not work on
a <b>std::auto_ptr&lt;T&gt; const.</b></p>
<h2><a name="Handle/Body">Handle/Body</a> Idiom</h2>
<p>One common usage of <b>scoped_ptr</b> is to implement a handle/body (also called
pimpl) idiom which avoids exposing the body (implementation) in the header
file.</p>
<p>The <a href="example/scoped_ptr_example_test.cpp">scoped_ptr_example_test.cpp</a>
sample program includes a header file, <a href="example/scoped_ptr_example.hpp">scoped_ptr_example.hpp</a>,
which uses a <b>scoped_ptr&lt;&gt;</b> to an incomplete type to hide the
implementation. The instantiation of member functions which require a complete
type occurs in the <a href="example/scoped_ptr_example.cpp">scoped_ptr_example.cpp</a>
implementation file.</p>
<h2>Frequently Asked Questions</h2>
<p><b>Q</b>. Why doesn't <b>scoped_ptr</b> have a release() member?<br>
<b>A</b>. When reading source code, it is valuable to be able to draw
conclusions about program behavior based on the types being used. If <STRONG>scoped_ptr</STRONG>
had a release() member, it would become possible to transfer ownership of the
held pointer, weakening its role as a way of limiting resource lifetime to a
given context. Use <STRONG>std::auto_ptr</STRONG> where transfer of ownership
is required. (supplied by Dave Abrahams)</p>
<hr>
<p>$Date</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

View File

@ -1,183 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>shared_array</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0">shared_array class template</h1>
<p>The <b>shared_array</b> class template stores a pointer to a dynamically
allocated array. (Dynamically allocated array are allocated with the C++ <b>new[]</b>
expression.) The object pointed to is guaranteed to be deleted when the last <b>shared_array</b>
pointing to it is destroyed or reset.</p>
<p>Every <b>shared_array</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_array</b>
works with the standard library's associative containers.</p>
<p>Normally, a <b>shared_array</b> cannot correctly hold a pointer to an object
that has been allocated with the non-array form of <STRONG>new</STRONG>. See <a href="shared_ptr.htm">
<b>shared_ptr</b></a> for that usage.</p>
<p>Because the implementation uses reference counting, cycles of <b>shared_array</b>
instances will not be reclaimed. For example, if <b>main()</b> holds a <b>shared_array</b>
to <b>A</b>, which directly or indirectly holds a <b>shared_array</b> back to <b>A</b>,
<b>A</b>'s use count will be 2. Destruction of the original <b>shared_array</b>
will leave <b>A</b> dangling with a use count of 1.</p>
<p>A <b>shared_ptr</b> to a <b>std::vector</b> is an alternative to a <b>shared_array</b>
that is a bit heavier duty but far more flexible.</p>
<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>.</p>
<h2>Synopsis</h2>
<pre>namespace boost {
template&lt;class T&gt; class shared_array {
public:
typedef T <a href="#element_type">element_type</a>;
explicit <a href="#constructors">shared_array</a>(T * p = 0);
template&lt;class D&gt; <a href="#constructors">shared_array</a>(T * p, D d);
<a href="#destructor">~shared_array</a>(); // never throws
<a href="#constructors">shared_array</a>(shared_array const &amp; r); // never throws
shared_array &amp; <a href="#assignment">operator=</a>(shared_array const &amp; r); // never throws
void <a href="#reset">reset</a>(T * p = 0);
template&lt;class D&gt; void <a href="#reset">reset</a>(T * p, D d);
T &amp; <a href="#indexing">operator[]</a>(std::ptrdiff_t i) 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
operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws
void <a href="#swap">swap</a>(shared_array&lt;T&gt; &amp; b); // never throws
};
template&lt;class T&gt;
bool <a href="#comparison">operator==</a>(shared_array&lt;T&gt; const &amp; a, shared_array&lt;T&gt; const &amp; b); // never throws
template&lt;class T&gt;
bool <a href="#comparison">operator!=</a>(shared_array&lt;T&gt; const &amp; a, shared_array&lt;T&gt; const &amp; b); // never throws
template&lt;class T&gt;
bool <a href="#comparison">operator&lt;</a>(shared_array&lt;T&gt; const &amp; a, shared_array&lt;T&gt; const &amp; b); // never throws
template&lt;class T&gt; void <a href="#free-swap">swap</a>(shared_array&lt;T&gt; &amp; a, shared_array&lt;T&gt; &amp; b); // never throws
}</pre>
<h2>Members</h2>
<h3><a name="element_type">element_type</a></h3>
<pre>typedef T element_type;</pre>
<p>Provides the type of the stored pointer.</p>
<h3><a name="constructors">constructors</a></h3>
<pre>explicit shared_array(T * p = 0);</pre>
<p>Constructs a <b>shared_array</b>, storing a copy of <b>p</b>, which must be a
pointer to an array 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_array</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&lt;class D&gt; shared_array(T * p, D d);</pre>
<p>Constructs a <b>shared_array</b>, storing a copy of <b>p</b> and of <b>d</b>.
Afterwards, the <a href="#use_count">use count</a> is 1. <b>D</b>'s copy
constructor and destructor must not throw. When the the time comes to delete
the array 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_array(shared_array const &amp; r); // never throws</pre>
<p>Constructs a <b>shared_array</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.</p>
<h3><a name="destructor">destructor</a></h3>
<pre>~shared_array(); // never throws</pre>
<p>Decrements the <a href="#use_count">use count</a>. Then, if the use count is 0,
deletes the array 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="assignment">assignment</a></h3>
<pre>shared_array &amp; operator=(shared_array const &amp; r); // never throws</pre>
<p>Constructs a new <b>shared_array</b> as described <a href="#constructors">above</a>,
then replaces this <b>shared_array</b> with the new one, destroying the
replaced object.</p>
<h3><a name="reset">reset</a></h3>
<pre>void reset(T * p = 0);</pre>
<p>Constructs a new <b>shared_array</b> as described <a href="#constructors">above</a>,
then replaces this <b>shared_array</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&lt;class D&gt; void reset(T * p, D d);</pre>
<p>Constructs a new <b>shared_array</b> as described <a href="#constructors">above</a>,
then replaces this <b>shared_array</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="indexing">indexing</a></h3>
<pre>T &amp; operator[](std::ptrdiff_t i) const; // never throws</pre>
<p>Returns a reference to element <b>i</b> of the array pointed to by the stored
pointer. Behavior is undefined and almost certainly undesirable if the stored
pointer is 0, or if <b>i</b> is less than 0 or is greater than or equal to the
number of elements in the array.</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_array</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_array</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_array</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="conversions">conversions</a></h3>
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
<p>Returns an unspecified value that, when used in boolean contexts, is equivalent
to <code>get() != 0</code>.</p>
<h3><a name="swap">swap</a></h3>
<pre>void swap(shared_ptr &amp; 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&lt;class T&gt;
bool operator==(shared_array&lt;T&gt; const &amp; a, shared_array&lt;T&gt; const &amp; b); // never throws
template&lt;class T&gt;
bool operator!=(shared_array&lt;T&gt; const &amp; a, shared_array&lt;T&gt; const &amp; b); // never throws
template&lt;class T&gt;
bool operator&lt;(shared_array&lt;T&gt; const &amp; a, shared_array&lt;T&gt; const &amp; 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&lt;</b> overload is provided to define an ordering so that <b>shared_array</b>
objects can be used in associative containers such as <b>std::map</b>. The
implementation uses <b>std::less&lt;T *&gt;</b> to perform the comparison. This
ensures that the comparison is handled correctly, since the standard mandates
that relational operations on pointers are unspecified (5.9 [expr.rel]
paragraph 2) but <b>std::less&lt;&gt;</b> on pointers is well-defined (20.3.3
[lib.comparisons] paragraph 8).</p>
<h3><a name="free-swap">swap</a></h3>
<pre>template&lt;class T&gt;
void swap(shared_array&lt;T&gt; &amp; a, shared_array&lt;T&gt; &amp; 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>
<hr>
<p>$Date$</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

View File

@ -1,858 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>shared_ptr</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0">shared_ptr class template</h1>
<p><a href="#Introduction">Introduction</a><br>
<a href="#BestPractices">Best Practices</a><br>
<a href="#Synopsis">Synopsis</a><br>
<a href="#Members">Members</a><br>
<a href="#functions">Free Functions</a><br>
<a href="#example">Example</a><br>
<a href="#HandleBody">Handle/Body Idiom</a><br>
<a href="#ThreadSafety">Thread Safety</a><br>
<a href="#FAQ">Frequently Asked Questions</a><br>
<a href="smarttests.htm">Smart Pointer Timings</a><br>
<a href="sp_techniques.html">Programming Techniques</a></p>
<h2 id="Introduction">Introduction</h2>
<p>The <code>shared_ptr</code> class template stores a pointer to a dynamically allocated
object, typically with a C++ <em>new-expression</em>. The object pointed to is
guaranteed to be deleted when the last <code>shared_ptr</code> pointing to it is
destroyed or reset.</p>
<blockquote><em>Example:</em><br><pre>shared_ptr&lt;X&gt; p1( new X );
shared_ptr&lt;void&gt; p2( new int(5) );
</pre></blockquote>
<p><code>shared_ptr</code> deletes the exact pointer that has been passed at construction time,
complete with its original type, regardless of the template parameter. In the second example above,
when <code>p2</code> is destroyed or reset, it will call <code>delete</code> on the original <code>int*</code>
that has been passed to the constructor, even though <code>p2</code> itself is of type
<code>shared_ptr&lt;void&gt;</code> and stores a pointer of type <code>void*</code>.</p>
<p>Every <code>shared_ptr</code> meets the <code>CopyConstructible</code>, <code>MoveConstructible</code>,
<code>CopyAssignable</code> and <code>MoveAssignable</code>
requirements of the C++ Standard Library, and can be used in standard
library containers. Comparison operators are supplied so that <code>shared_ptr</code>
works with the standard library's associative containers.</p>
<p>Because the implementation uses reference counting, cycles of <code>shared_ptr</code> instances
will not be reclaimed. For example, if <code>main()</code> holds a <code>shared_ptr</code> to
<code>A</code>, which directly or indirectly holds a <code>shared_ptr</code> back to <code>A</code>,
<code>A</code>'s use count will be 2. Destruction of the original <code>shared_ptr</code> will
leave <code>A</code> dangling with a use count of 1. Use <a href="weak_ptr.htm">weak_ptr</a>
to "break cycles."</p>
<p>The class template is parameterized on <code>T</code>, the type of the object pointed
to. <code>shared_ptr</code> and most of its member functions place no
requirements on <code>T</code>; it is allowed to be an incomplete type, or
<code>void</code>. Member functions that do place additional requirements
(<a href="#pointer_constructor">constructors</a>, <a href="#reset">reset</a>) are explicitly
documented below.</p>
<p><code>shared_ptr&lt;T&gt;</code> can be implicitly converted to <code>shared_ptr&lt;U&gt;</code>
whenever <code>T*</code> can be implicitly converted to <code>U*</code>.
In particular, <code>shared_ptr&lt;T&gt;</code> is implicitly convertible
to <code>shared_ptr&lt;T const&gt;</code>, to <code>shared_ptr&lt;U&gt;</code>
where <code>U</code> is an accessible base of <code>T</code>, and to <code>
shared_ptr&lt;void&gt;</code>.</p>
<p><code>shared_ptr</code> is now part of the C++11 Standard, as <code>std::shared_ptr</code>.</p>
<p>Starting with Boost release 1.53, <code>shared_ptr</code> can be used to hold a pointer to a dynamically
allocated array. This is accomplished by using an array type (<code>T[]</code> or <code>T[N]</code>) as
the template parameter. There is almost no difference between using an unsized array, <code>T[]</code>,
and a sized array, <code>T[N]</code>; the latter just enables <code>operator[]</code> to perform a range check
on the index.</p>
<blockquote><em>Example:</em><br><pre>shared_ptr&lt;double[1024]&gt; p1( new double[1024] );
shared_ptr&lt;double[]&gt; p2( new double[n] );
</pre></blockquote>
<h2 id="BestPractices">Best Practices</h2>
<p>A simple guideline that nearly eliminates the possibility of memory leaks is:
always use a named smart pointer variable to hold the result of <code>new</code>.
Every occurence of the <code>new</code> keyword in the code should have the
form:</p>
<pre>shared_ptr&lt;T&gt; p(new Y);</pre>
<p>It is, of course, acceptable to use another smart pointer in place of <code>shared_ptr</code>
above; having <code>T</code> and <code>Y</code> be the same type, or
passing arguments to <code>Y</code>'s constructor is also OK.</p>
<p>If you observe this guideline, it naturally follows that you will have no
explicit <code>delete</code> statements; <code>try/catch</code> constructs will
be rare.</p>
<p>Avoid using unnamed <code>shared_ptr</code> temporaries to save typing; to
see why this is dangerous, consider this example:</p>
<pre>void f(shared_ptr&lt;int&gt;, int);
int g();
void ok()
{
shared_ptr&lt;int&gt; p( new int(2) );
f( p, g() );
}
void bad()
{
f( shared_ptr&lt;int&gt;( new int(2) ), g() );
}
</pre>
<p>The function <code>ok</code> follows the guideline to the letter, whereas
<code>bad</code> constructs the temporary <code>shared_ptr</code> in place,
admitting the possibility of a memory leak. Since function arguments are
evaluated in unspecified order, it is possible for <code>new int(2)</code> to
be evaluated first, <code>g()</code> second, and we may never get to the
<code>shared_ptr</code>constructor if <code>g</code> throws an exception.
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">
here</a>) of the issue for more information.</p>
<p>The exception safety problem described above may also be eliminated by using
the <a href="make_shared.html"><code>make_shared</code></a>
or <a href="make_shared.html"><code>allocate_shared</code></a>
factory functions defined in <code>boost/make_shared.hpp</code>.
These factory functions also provide an efficiency benefit by consolidating allocations.</p>
<h2 id="Synopsis">Synopsis</h2>
<pre>namespace boost {
class bad_weak_ptr: public std::exception;
template&lt;class T&gt; class <a href="weak_ptr.htm" >weak_ptr</a>;
template&lt;class T&gt; class shared_ptr {
public:
typedef <em>see below</em> <a href="#element_type" >element_type</a>;
<a href="#default_constructor" >shared_ptr</a>(); // never throws
<a href="#default_constructor" >shared_ptr</a>(std::nullptr_t); // never throws
template&lt;class Y&gt; explicit <a href="#pointer_constructor" >shared_ptr</a>(Y * p);
template&lt;class Y, class D&gt; <a href="#deleter_constructor" >shared_ptr</a>(Y * p, D d);
template&lt;class Y, class D, class A&gt; <a href="#deleter_constructor" >shared_ptr</a>(Y * p, D d, A a);
template&lt;class D&gt; <a href="#deleter_constructor" >shared_ptr</a>(std::nullptr_t p, D d);
template&lt;class D, class A&gt; <a href="#deleter_constructor" >shared_ptr</a>(std::nullptr_t p, D d, A a);
<a href="#destructor" >~shared_ptr</a>(); // never throws
<a href="#copy_constructor" >shared_ptr</a>(shared_ptr const &amp; r); // never throws
template&lt;class Y&gt; <a href="#copy_constructor" >shared_ptr</a>(shared_ptr&lt;Y&gt; const &amp; r); // never throws
<a href="#move_constructor" >shared_ptr</a>(shared_ptr &amp;&amp; r); // never throws
template&lt;class Y&gt; <a href="#move_constructor" >shared_ptr</a>(shared_ptr&lt;Y&gt; &amp;&amp; r); // never throws
template&lt;class Y&gt; <a href="#aliasing_constructor" >shared_ptr</a>(shared_ptr&lt;Y&gt; const &amp; r, element_type * p); // never throws
template&lt;class Y&gt; <a href="#aliasing_move_constructor" >shared_ptr</a>(shared_ptr&lt;Y&gt; &amp;&amp; r, element_type * p); // never throws
template&lt;class Y&gt; explicit <a href="#weak_ptr_constructor" >shared_ptr</a>(<a href="weak_ptr.htm" >weak_ptr</a>&lt;Y&gt; const &amp; r);
template&lt;class Y&gt; explicit <a href="#auto_ptr_constructor" >shared_ptr</a>(std::auto_ptr&lt;Y&gt; &amp; r);
template&lt;class Y&gt; <a href="#auto_ptr_constructor" >shared_ptr</a>(std::auto_ptr&lt;Y&gt; &amp;&amp; r);
template&lt;class Y, class D&gt; <a href="#unique_ptr_constructor" >shared_ptr</a>(std::unique_ptr&lt;Y, D&gt; &amp;&amp; r);
shared_ptr &amp; <a href="#assignment" >operator=</a>(shared_ptr const &amp; r); // never throws
template&lt;class Y&gt; shared_ptr &amp; <a href="#assignment" >operator=</a>(shared_ptr&lt;Y&gt; const &amp; r); // never throws
shared_ptr &amp; <a href="#assignment" >operator=</a>(shared_ptr const &amp;&amp; r); // never throws
template&lt;class Y&gt; shared_ptr &amp; <a href="#assignment" >operator=</a>(shared_ptr&lt;Y&gt; const &amp;&amp; r); // never throws
template&lt;class Y&gt; shared_ptr &amp; <a href="#assignment" >operator=</a>(std::auto_ptr&lt;Y&gt; &amp; r);
template&lt;class Y&gt; shared_ptr &amp; <a href="#assignment" >operator=</a>(std::auto_ptr&lt;Y&gt; &amp;&amp; r);
template&lt;class Y, class D&gt; shared_ptr &amp; <a href="#assignment" >operator=</a>(std::unique_ptr&lt;Y, D&gt; &amp;&amp; r);
shared_ptr &amp; <a href="#assignment" >operator=</a>(std::nullptr_t); // never throws
void <a href="#reset" >reset</a>(); // never throws
template&lt;class Y&gt; void <a href="#reset" >reset</a>(Y * p);
template&lt;class Y, class D&gt; void <a href="#reset" >reset</a>(Y * p, D d);
template&lt;class Y, class D, class A&gt; void <a href="#reset" >reset</a>(Y * p, D d, A a);
template&lt;class Y&gt; void <a href="#reset" >reset</a>(shared_ptr&lt;Y&gt; const &amp; r, element_type * p); // never throws
T &amp; <a href="#indirection" >operator*</a>() const; // never throws; only valid when T is not an array type
T * <a href="#indirection" >operator-&gt;</a>() const; // never throws; only valid when T is not an array type
element_type &amp; <a href="#indirection" >operator[]</a>(std::ptrdiff_t i) const; // never throws; only valid when T is an array type
element_type * <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
explicit <a href="#conversions" >operator bool</a>() const; // never throws
void <a href="#swap" >swap</a>(shared_ptr &amp; b); // never throws
template&lt;class Y&gt; bool <a href="#owner_before" >owner_before</a>(shared_ptr&lt;Y&gt; const &amp; rhs) const; // never throws
template&lt;class Y&gt; bool <a href="#owner_before" >owner_before</a>(weak_ptr&lt;Y&gt; const &amp; rhs) const; // never throws
};
template&lt;class T, class U&gt;
bool <a href="#comparison" >operator==</a>(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b); // never throws
template&lt;class T, class U&gt;
bool <a href="#comparison" >operator!=</a>(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b); // never throws
template&lt;class T, class U&gt;
bool <a href="#comparison" >operator&lt;</a>(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b); // never throws
template&lt;class T&gt;
bool <a href="#comparison" >operator==</a>(shared_ptr&lt;T&gt; const &amp; p, std::nullptr_t); // never throws
template&lt;class T&gt;
bool <a href="#comparison" >operator==</a>(std::nullptr_t, shared_ptr&lt;T&gt; const &amp; p); // never throws
template&lt;class T&gt;
bool <a href="#comparison" >operator!=</a>(shared_ptr&lt;T&gt; const &amp; p, std::nullptr_t); // never throws
template&lt;class T&gt;
bool <a href="#comparison" >operator!=</a>(std::nullptr_t, shared_ptr&lt;T&gt; const &amp; p); // never throws
template&lt;class T&gt; void <a href="#free-swap" >swap</a>(shared_ptr&lt;T&gt; &amp; a, shared_ptr&lt;T&gt; &amp; b); // never throws
template&lt;class T&gt; typename shared_ptr&lt;T&gt;::element_type * <a href="#get_pointer" >get_pointer</a>(shared_ptr&lt;T&gt; const &amp; p); // never throws
template&lt;class T, class U&gt;
shared_ptr&lt;T&gt; <a href="#static_pointer_cast" >static_pointer_cast</a>(shared_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;class T, class U&gt;
shared_ptr&lt;T&gt; <a href="#const_pointer_cast" >const_pointer_cast</a>(shared_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;class T, class U&gt;
shared_ptr&lt;T&gt; <a href="#dynamic_pointer_cast" >dynamic_pointer_cast</a>(shared_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;class T, class U&gt;
shared_ptr&lt;T&gt; <a href="#reinterpret_pointer_cast" >reinterpret_pointer_cast</a>(shared_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;class E, class T, class Y&gt;
std::basic_ostream&lt;E, T&gt; &amp; <a href="#insertion-operator" >operator&lt;&lt;</a> (std::basic_ostream&lt;E, T&gt; &amp; os, shared_ptr&lt;Y&gt; const &amp; p);
template&lt;class D, class T&gt;
D * <a href="#get_deleter">get_deleter</a>(shared_ptr&lt;T&gt; const &amp; p);
}</pre>
<h2 id="Members">Members</h2>
<h3 id="element_type">element_type</h3>
<pre>typedef <em>...</em> element_type;</pre>
<blockquote>
<p><code>element_type</code> is <code>T</code> when <code>T</code> is not an array type,
and <code>U</code> when <code>T</code> is <code>U[]</code> or <code>U[N]</code>.</p>
</blockquote>
<h3 id="default_constructor">default constructor</h3>
<pre>shared_ptr(); // never throws
shared_ptr(std::nullptr_t); // never throws</pre>
<blockquote>
<p><b>Effects:</b> Constructs an <em>empty</em> <code>shared_ptr</code>.</p>
<p><b>Postconditions:</b> <code>use_count() == 0 &amp;&amp; get() == 0</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<p><em>[The nothrow guarantee is important, since <code>reset()</code> is specified
in terms of the default constructor; this implies that the constructor must not
allocate memory.]</em></p>
<h3 id="pointer_constructor">pointer constructor</h3>
<pre>template&lt;class Y&gt; explicit shared_ptr(Y * p);</pre>
<blockquote>
<p><b>Requirements:</b>
<code>Y</code> must be a complete type.
The expression <code>delete[] p</code>, when <code>T</code> is an array type, or <code>delete p</code>,
when <code>T</code> is not an array type,
must be well-formed, must not invoke undefined behavior, and must not throw exceptions.
When <code>T</code> is <code>U[N]</code>, <code>Y (*) [N]</code> must be convertible to <code>T*</code>;
when <code>T</code> is <code>U[]</code>, <code>Y (*) []</code> must be convertible to <code>T*</code>;
otherwise, <code>Y*</code> must be convertible to <code>T*</code>.
</p>
<p><b>Effects:</b>
When <code>T</code> is not an array type, constructs a <code>shared_ptr</code> that <em>owns</em>
the pointer <code>p</code>.
Otherwise, constructs a <code>shared_ptr</code> that <em>owns</em>
<code>p</code> and a deleter of an unspecified type that calls <code>delete[] p</code>.</p>
<p><b>Postconditions:</b> <code>use_count() == 1 &amp;&amp; get() == p</code>.
If <code>T</code> is not an array type and <code>p</code> is unambiguously convertible to <code>
<a href="enable_shared_from_this.html">enable_shared_from_this</a>&lt;V&gt;*</code>
for some <code>V</code>, <code>p-&gt;shared_from_this()</code> returns a copy of
<code>*this</code>.</p>
<p><b>Throws:</b> <code>std::bad_alloc</code>, or an implementation-defined
exception when a resource other than memory could not be obtained.</p>
<p><b>Exception safety:</b> If an exception is thrown, the constructor calls
<code>delete[] p</code>, when <code>T</code> is an array type,
or <code>delete p</code>, when <code>T</code> is not an array type.</p>
<p><b>Notes:</b> <code>p</code> must be a pointer to an object that was
allocated via a C++ <code>new</code> expression or be 0. The postcondition that <a href="#use_count">
use count</a> is 1 holds even if <code>p</code> is 0; invoking <code>delete</code>
on a pointer that has a value of 0 is harmless.</p>
</blockquote>
<p><em>[This constructor is a template in order to remember the actual
pointer type passed. The destructor will call <code>delete</code> with the
same pointer, complete with its original type, even when <code>T</code> does
not have a virtual destructor, or is <code>void</code>.]</em></p>
<h3 id="deleter_constructor">constructors taking a deleter</h3>
<pre>template&lt;class Y, class D&gt; shared_ptr(Y * p, D d);
template&lt;class Y, class D, class A&gt; shared_ptr(Y * p, D d, A a);
template&lt;class D&gt; shared_ptr(std::nullptr_t p, D d);
template&lt;class D, class A&gt; shared_ptr(std::nullptr_t p, D d, A a);</pre>
<blockquote>
<p><b>Requirements:</b>
<code>D</code> must be <code>CopyConstructible</code>. The copy constructor and destructor
of <code>D</code> must not throw. The expression <code>d(p)</code> must be
well-formed, must not invoke undefined behavior, and must not throw exceptions.
<code>A</code> must be an <em>Allocator</em>, as described in section 20.1.5
(<code>Allocator requirements</code>) of the C++ Standard.
When <code>T</code> is <code>U[N]</code>, <code>Y (*) [N]</code> must be convertible to <code>T*</code>;
when <code>T</code> is <code>U[]</code>, <code>Y (*) []</code> must be convertible to <code>T*</code>;
otherwise, <code>Y*</code> must be convertible to <code>T*</code>.
</p>
<p><b>Effects:</b> Constructs a <code>shared_ptr</code> that <em>owns</em> the pointer <code>
p</code> and the deleter <code>d</code>. The constructors taking an allocator <code>a</code>
allocate memory using a copy of <code>a</code>.</p>
<p><b>Postconditions:</b> <code>use_count() == 1 &amp;&amp; get() == p</code>.
If <code>T</code> is not an array type and <code>p</code> is unambiguously convertible to <code>
<a href="enable_shared_from_this.html">enable_shared_from_this</a>&lt;V&gt;*</code>
for some <code>V</code>, <code>p-&gt;shared_from_this()</code> returns a copy of
<code>*this</code>.</p>
<p><b>Throws:</b> <code>std::bad_alloc</code>, or an implementation-defined
exception when a resource other than memory could not be obtained.</p>
<p><b>Exception safety:</b> If an exception is thrown, <code>d(p)</code> is called.</p>
<p><b>Notes:</b> When the the time comes to delete the object pointed to by <code>p</code>,
the stored copy of <code>d</code> is invoked with the stored copy of <code>p</code>
as an argument.</p>
</blockquote>
<p><em>[Custom deallocators allow a factory function returning a <code>shared_ptr</code>
to insulate the user from its memory allocation strategy. Since the deallocator
is not part of the type, changing the allocation strategy does not break source
or binary compatibility, and does not require a client recompilation. For
example, a "no-op" deallocator is useful when returning a <code>shared_ptr</code>
to a statically allocated object, and other variations allow a <code>shared_ptr</code>
to be used as a wrapper for another smart pointer, easing interoperability.</em></p>
<p><em>The support for custom deallocators does not impose significant overhead. Other <code>
shared_ptr</code> features still require a deallocator to be kept.</em></p>
<p><em>The requirement that the copy constructor of <code>D</code> does not throw comes from
the pass by value. If the copy constructor throws, the pointer would leak.]</em></p>
<h3 id="copy_constructor">copy and converting constructors</h3>
<pre>shared_ptr(shared_ptr const &amp; r); // never throws
template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; r); // never throws</pre>
<blockquote>
<p><b>Requires:</b> <code>Y*</code> should be convertible to <code>T*</code>.</p>
<p><b>Effects:</b> If <code>r</code> is <em>empty</em>, constructs an <em>empty</em> <code>shared_ptr</code>;
otherwise, constructs a <code>shared_ptr</code> that <em>shares ownership</em> with <code>r</code>.</p>
<p><b>Postconditions:</b> <code>get() == r.get() &amp;&amp; use_count() ==
r.use_count()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3 id="move_constructor">move constructors</h3>
<pre>shared_ptr(shared_ptr &amp;&amp; r); // never throws
template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; &amp;&amp; r); // never throws</pre>
<blockquote>
<p><b>Requires:</b> <code>Y*</code> should be convertible to <code>T*</code>.</p>
<p><b>Effects:</b> Move-constructs a <code>shared_ptr</code> from <code>r</code>.</p>
<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>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3 id="aliasing_constructor">aliasing constructor</h3>
<pre>template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; r, element_type * p); // never throws</pre>
<blockquote>
<p><b>Effects:</b> constructs a <code>shared_ptr</code> that <em>shares ownership</em> with
<code>r</code> and stores <code>p</code>.</p>
<p><b>Postconditions:</b> <code>get() == p &amp;&amp; use_count() == r.use_count()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3 id="aliasing_move_constructor">aliasing move constructor</h3>
<pre>template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; &amp;&amp; r, element_type * p); // never throws</pre>
<blockquote>
<p>
<b>Effects:</b> Move-constructs a <code>shared_ptr</code> from <code>r</code>, while
storing <code>p</code> instead.
</p>
<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>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3 id="weak_ptr_constructor">weak_ptr constructor</h3>
<pre>template&lt;class Y&gt; explicit shared_ptr(<a href="weak_ptr.htm" >weak_ptr</a>&lt;Y&gt; const &amp; r);</pre>
<blockquote>
<p><b>Requires:</b> <code>Y*</code> should be convertible to <code>T*</code>.</p>
<p><b>Effects:</b> Constructs a <code>shared_ptr</code> that <em>shares ownership</em> with
<code>r</code> and stores a copy of the pointer stored in <code>r</code>.</p>
<p><b>Postconditions:</b> <code>use_count() == r.use_count()</code>.</p>
<p><b>Throws:</b> <code>bad_weak_ptr</code> when <code>r.use_count() == 0</code>.</p>
<p><b>Exception safety:</b> If an exception is thrown, the constructor has no
effect.</p>
</blockquote>
<h3 id="auto_ptr_constructor">auto_ptr constructors</h3>
<pre>template&lt;class Y&gt; shared_ptr(std::auto_ptr&lt;Y&gt; &amp; r);
template&lt;class Y&gt; shared_ptr(std::auto_ptr&lt;Y&gt; &amp;&amp; r);</pre>
<blockquote>
<p><b>Requires:</b> <code>Y*</code> should be convertible to <code>T*</code>.</p>
<p><b>Effects:</b> Constructs a <code>shared_ptr</code>, as if by storing a copy of <code>r.release()</code>.</p>
<p><b>Postconditions:</b> <code>use_count() == 1</code>.</p>
<p><b>Throws:</b> <code>std::bad_alloc</code>, or an implementation-defined
exception when a resource other than memory could not be obtained.</p>
<p><b>Exception safety:</b> If an exception is thrown, the constructor has no
effect.</p>
</blockquote>
<h3 id="unique_ptr_constructor">unique_ptr constructor</h3>
<pre>template&lt;class Y, class D&gt; shared_ptr(std::unique_ptr&lt;Y, D&gt; &amp;&amp; r);</pre>
<blockquote>
<p><b>Requires:</b> <code>Y*</code> should be convertible to <code>T*</code>.</p>
<p><b>Effects:</b>
Equivalent to <code>shared_ptr(r.release(), r.get_deleter())</code> when <code>D</code> is not a reference type.
Otherwise, equivalent to <code>shared_ptr(r.release(), <em>del</em>)</code>, where <em>del</em> is a deleter
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>
<p><b>Postconditions:</b> <code>use_count() == 1</code>.</p>
<p><b>Throws:</b> <code>std::bad_alloc</code>, or an implementation-defined
exception when a resource other than memory could not be obtained.</p>
<p><b>Exception safety:</b> If an exception is thrown, the constructor has no
effect.</p>
</blockquote>
<h3 id="destructor">destructor</h3>
<pre>~shared_ptr(); // never throws</pre>
<blockquote>
<p><b>Effects:</b></p>
<ul>
<li>
If <code>*this</code> is <em>empty</em>, or <em>shares ownership</em> with
another <code>shared_ptr</code> instance (<code>use_count() &gt; 1</code>),
there are no side effects.</li>
<li>
Otherwise, if <code>*this</code> <em>owns</em> a pointer <code>p</code>
and a deleter <code>d</code>, <code>d(p)</code>
is called.</li>
<li>
Otherwise, <code>*this</code> <em>owns</em> a pointer <code>p</code>,
and <code>delete p</code> is called.</li>
</ul>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3 id="assignment">assignment</h3>
<pre>shared_ptr &amp; operator=(shared_ptr const &amp; r); // never throws
template&lt;class Y&gt; shared_ptr &amp; operator=(shared_ptr&lt;Y&gt; const &amp; r); // never throws
template&lt;class Y&gt; shared_ptr &amp; operator=(std::auto_ptr&lt;Y&gt; &amp; r);</pre>
<blockquote>
<p><b>Effects:</b> Equivalent to <code>shared_ptr(r).swap(*this)</code>.</p>
<p><b>Returns:</b> <code>*this</code>.</p>
<p><b>Notes:</b> The use count updates caused by the temporary object construction
and destruction are not considered observable side effects, and the
implementation is free to meet the effects (and the implied guarantees) via
different means, without creating a temporary. In particular, in the example:</p>
<pre>shared_ptr&lt;int&gt; p(new int);
shared_ptr&lt;void&gt; q(p);
p = p;
q = p;
</pre>
<p>both assignments may be no-ops.</p>
</blockquote>
<pre>shared_ptr &amp; operator=(shared_ptr &amp;&amp; r); // never throws
template&lt;class Y&gt; shared_ptr &amp; operator=(shared_ptr&lt;Y&gt; &amp;&amp; r); // never throws
template&lt;class Y&gt; shared_ptr &amp; operator=(std::auto_ptr&lt;Y&gt; &amp;&amp; r);
template&lt;class Y, class D&gt; shared_ptr &amp; operator=(std::unique_ptr&lt;Y, D&gt; &amp;&amp; r);</pre>
<blockquote>
<p><b>Effects:</b> Equivalent to <code>shared_ptr(std::move(r)).swap(*this)</code>.</p>
<p><b>Returns:</b> <code>*this</code>.</p>
</blockquote>
<pre>shared_ptr &amp; operator=(std::nullptr_t); // never throws</pre>
<blockquote>
<p><b>Effects:</b> Equivalent to <code>shared_ptr().swap(*this)</code>.</p>
<p><b>Returns:</b> <code>*this</code>.</p>
</blockquote>
<h3 id="reset">reset</h3>
<pre>void reset(); // never throws</pre>
<blockquote>
<p><b>Effects:</b> Equivalent to <code>shared_ptr().swap(*this)</code>.</p>
</blockquote>
<pre>template&lt;class Y&gt; void reset(Y * p);</pre>
<blockquote>
<p><b>Effects:</b> Equivalent to <code>shared_ptr(p).swap(*this)</code>.</p>
</blockquote>
<pre>template&lt;class Y, class D&gt; void reset(Y * p, D d);</pre>
<blockquote>
<p><b>Effects:</b> Equivalent to <code>shared_ptr(p, d).swap(*this)</code>.</p>
</blockquote>
<pre>template&lt;class Y, class D, class A&gt; void reset(Y * p, D d, A a);</pre>
<blockquote>
<p><b>Effects:</b> Equivalent to <code>shared_ptr(p, d, a).swap(*this)</code>.</p>
</blockquote>
<pre>template&lt;class Y&gt; void reset(shared_ptr&lt;Y&gt; const &amp; r, element_type * p); // never throws</pre>
<blockquote>
<p><b>Effects:</b> Equivalent to <code>shared_ptr(r, p).swap(*this)</code>.</p>
</blockquote>
<h3 id="indirection">indirection</h3>
<pre>T &amp; operator*() const; // never throws</pre>
<blockquote>
<p><b>Requirements:</b> <code>T</code> should not be an array type. The stored pointer must not be 0.</p>
<p><b>Returns:</b> a reference to the object pointed to by the stored pointer.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>T * operator-&gt;() const; // never throws</pre>
<blockquote>
<p><b>Requirements:</b> <code>T</code> should not be an array type. The stored pointer must not be 0.</p>
<p><b>Returns:</b> the stored pointer.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>element_type &amp; operator[](std::ptrdiff_t i) const; // never throws</pre>
<blockquote>
<p><b>Requirements:</b> <code>T</code> should be an array type. The stored pointer must not be 0.
<code>i &gt;= 0</code>. If <code>T</code> is <code>U[N]</code>, <code>i &lt; N</code>.</p>
<p><b>Returns:</b> <code>get()[i]</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3 id="get">get</h3>
<pre>element_type * get() const; // never throws</pre>
<blockquote>
<p><b>Returns:</b> the stored pointer.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3 id="unique">unique</h3>
<pre>bool unique() const; // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>use_count() == 1</code>.</p>
<p><b>Throws:</b> nothing.</p>
<p><b>Notes:</b> <code>unique()</code> may be faster than <code>use_count()</code>.
If you are using <code>unique()</code> to implement copy on write, do not rely
on a specific value when the stored pointer is zero.</p>
</blockquote>
<h3 id="use_count">use_count</h3>
<pre>long use_count() const; // never throws</pre>
<blockquote>
<p><b>Returns:</b> the number of <code>shared_ptr</code> objects, <code>*this</code> included,
that <i>share ownership</i> with <code>*this</code>, or 0 when <code>*this</code>
is <em>empty</em>.</p>
<p><b>Throws:</b> nothing.</p>
<p><b>Notes:</b> <code>use_count()</code> is not necessarily efficient. Use only
for debugging and testing purposes, not for production code.</p>
</blockquote>
<h3 id="conversions">conversions</h3>
<pre>explicit operator bool() const; // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>get() != 0</code>.</p>
<p><b>Throws:</b> nothing.</p>
<p><b>Notes:</b> This conversion operator allows <code>shared_ptr</code> objects to be
used in boolean contexts, like <code>if(p &amp;&amp; p-&gt;valid()) {}</code>.</p>
</blockquote>
<p><em>[The conversion to bool is not merely syntactic sugar. It allows <code>shared_ptr</code>s
to be declared in conditions when using <a href="#dynamic_pointer_cast">dynamic_pointer_cast</a>
or <a href="weak_ptr.htm#lock">weak_ptr::lock</a>.]</em></p>
<h3 id="swap">swap</h3>
<pre>void swap(shared_ptr &amp; b); // never throws</pre>
<blockquote>
<p><b>Effects:</b> Exchanges the contents of the two smart pointers.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3 id="owner_before">swap</h3>
<pre>template&lt;class Y&gt; bool owner_before(shared_ptr&lt;Y&gt; const &amp; rhs) const; // never throws
template&lt;class Y&gt; bool owner_before(weak_ptr&lt;Y&gt; const &amp; rhs) const; // never throws</pre>
<blockquote>
<p><b>Effects:</b> See the description of <a href="#comparison"><code>operator&lt;</code></a>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h2 id="functions">Free Functions</h2>
<h3 id="comparison">comparison</h3>
<pre>template&lt;class T, class U&gt;
bool operator==(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a.get() == b.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T, class U&gt;
bool operator!=(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>a.get() != b.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T&gt;
bool operator==(shared_ptr&lt;T&gt; const &amp; p, std::nullptr_t); // never throws
template&lt;class T&gt;
bool operator==(std::nullptr_t, shared_ptr&lt;T&gt; const &amp; p); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>p.get() == 0</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T&gt;
bool operator!=(shared_ptr&lt;T&gt; const &amp; p, std::nullptr_t); // never throws
template&lt;class T&gt;
bool operator!=(std::nullptr_t, shared_ptr&lt;T&gt; const &amp; p); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>p.get() != 0</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class T, class U&gt;
bool operator&lt;(shared_ptr&lt;T&gt; const &amp; a, shared_ptr&lt;U&gt; const &amp; b); // never throws</pre>
<blockquote>
<p><b>Returns:</b> an unspecified value such that</p>
<ul>
<li>
<code>operator&lt;</code> is a strict weak ordering as described in section 25.3 <code>[lib.alg.sorting]</code>
of the C++ standard;</li>
<li>
under the equivalence relation defined by <code>operator&lt;</code>, <code>!(a
&lt; b) &amp;&amp; !(b &lt; a)</code>, two <code>shared_ptr</code> instances
are equivalent if and only if they <em>share ownership</em> or are both <em>empty</em>.</li></ul>
<p><b>Throws:</b> nothing.</p>
<p><b>Notes:</b> Allows <code>shared_ptr</code> objects to be used as keys in
associative containers.</p>
</blockquote>
<p><em>[<code>Operator&lt;</code> has been preferred over a <code>std::less</code>
specialization for consistency and legality reasons, as <code>std::less</code>
is required to return the results of <code>operator&lt;</code>, and many
standard algorithms use <code>operator&lt;</code> instead of <code>std::less</code>
for comparisons when a predicate is not supplied. Composite objects, like <code>std::pair</code>,
also implement their <code>operator&lt;</code> in terms of their contained
subobjects' <code>operator&lt;</code>.</em></p>
<p><em>The rest of the comparison operators are omitted by design.]</em></p>
<h3 id="free-swap">swap</h3>
<pre>template&lt;class T&gt;
void swap(shared_ptr&lt;T&gt; &amp; a, shared_ptr&lt;T&gt; &amp; b); // never throws</pre>
<blockquote>
<p><b>Effects:</b> Equivalent to <code>a.swap(b)</code>.</p>
<p><b>Throws:</b> nothing.</p>
<p><b>Notes:</b> Matches the interface of <code>std::swap</code>. Provided as an aid to
generic programming.</p>
</blockquote>
<p><em>[<code>swap</code> is defined in the same namespace as <code>shared_ptr</code>
as this is currently the only legal way to supply a <code>swap</code> function
that has a chance to be used by the standard library.]</em></p>
<h3 id="get_pointer">get_pointer</h3>
<pre>template&lt;class T&gt;
typename shared_ptr&lt;T&gt;::element_type * get_pointer(shared_ptr&lt;T&gt; const &amp; p); // never throws</pre>
<blockquote>
<p><b>Returns:</b> <code>p.get()</code>.</p>
<p><b>Throws:</b> nothing.</p>
<p><b>Notes:</b> Provided as an aid to generic programming. Used by <a href="../bind/mem_fn.html">
mem_fn</a>.</p>
</blockquote>
<h3 id="static_pointer_cast">static_pointer_cast</h3>
<pre>template&lt;class T, class U&gt;
shared_ptr&lt;T&gt; static_pointer_cast(shared_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<blockquote>
<p><b>Requires:</b> The expression <code>static_cast&lt;T*&gt;( (U*)0 )</code>
must be well-formed.</p>
<p><b>Returns:</b> <code>shared_ptr&lt;T&gt;( r, static_cast&lt;typename shared_ptr&lt;T&gt;::element_type*&gt;(r.get()) )</code>.</p>
<p><b>Throws:</b> nothing.</p>
<p><b>Notes:</b> the seemingly equivalent expression
<code>shared_ptr&lt;T&gt;(static_cast&lt;T*&gt;(r.get()))</code>
will eventually result in undefined behavior, attempting to delete the same
object twice.</p>
</blockquote>
<h3 id="const_pointer_cast">const_pointer_cast</h3>
<pre>template&lt;class T, class U&gt;
shared_ptr&lt;T&gt; const_pointer_cast(shared_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<blockquote>
<p><b>Requires:</b> The expression <code>const_cast&lt;T*&gt;( (U*)0 )</code>
must be well-formed.</p>
<p><b>Returns:</b> <code>shared_ptr&lt;T&gt;( r, const_cast&lt;typename shared_ptr&lt;T&gt;::element_type*&gt;(r.get()) )</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3 id="dynamic_pointer_cast">dynamic_pointer_cast</h3>
<pre>template&lt;class T, class U&gt;
shared_ptr&lt;T&gt; dynamic_pointer_cast(shared_ptr&lt;U&gt; const &amp; r);</pre>
<blockquote>
<p><b>Requires:</b> The expression <code>dynamic_cast&lt;T*&gt;( (U*)0 )</code>
must be well-formed.</p>
<p><b>Returns:</b></p>
<ul>
<li>
When <code>dynamic_cast&lt;typename shared_ptr&lt;T&gt;::element_type*&gt;(r.get())</code> returns a nonzero value <code>p</code>,
<code>shared_ptr&lt;T&gt;(r, p)</code>;</li>
<li>
Otherwise, <code>shared_ptr&lt;T&gt;()</code>.</li></ul>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3 id="reinterpret_pointer_cast">reinterpret_pointer_cast</h3>
<pre>template&lt;class T, class U&gt;
shared_ptr&lt;T&gt; reinterpret_pointer_cast(shared_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<blockquote>
<p><b>Requires:</b> The expression <code>reinterpret_cast&lt;T*&gt;( (U*)0 )</code>
must be well-formed.</p>
<p><b>Returns:</b> <code>shared_ptr&lt;T&gt;( r, reinterpret_cast&lt;typename shared_ptr&lt;T&gt;::element_type*&gt;(r.get()) )</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3 id="insertion-operator">operator&lt;&lt;</h3>
<pre>template&lt;class E, class T, class Y&gt;
std::basic_ostream&lt;E, T&gt; &amp; operator&lt;&lt; (std::basic_ostream&lt;E, T&gt; &amp; os, shared_ptr&lt;Y&gt; const &amp; p);</pre>
<blockquote>
<p><b>Effects:</b> <code>os &lt;&lt; p.get();</code>.</p>
<p><b>Returns:</b> <code>os</code>.</p>
</blockquote>
<h3 id="get_deleter">get_deleter</h3>
<pre>template&lt;class D, class T&gt;
D * get_deleter(shared_ptr&lt;T&gt; const &amp; p);</pre>
<blockquote>
<p><b>Returns:</b> If <code>*this</code> <em>owns</em> a deleter <code>d</code>
of type (cv-unqualified) <code>D</code>, returns <code>&amp;d</code>;
otherwise returns 0.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h2 id="example">Example</h2>
<p>See <a href="example/shared_ptr_example.cpp">shared_ptr_example.cpp</a> for a
complete example program. The program builds a <code>std::vector</code> and <code>std::set</code>
of <code>shared_ptr</code> objects.</p>
<p>Note that after the containers have been populated, some of the <code>shared_ptr</code>
objects will have a use count of 1 rather than a use count of 2, since the set
is a <code>std::set</code> rather than a <code>std::multiset</code>, and thus does not
contain duplicate entries. Furthermore, the use count may be even higher at
various times while <code>push_back</code> and <code>insert</code> container operations are
performed. More complicated yet, the container operations may throw exceptions
under a variety of circumstances. Getting the memory management and exception
handling in this example right without a smart pointer would be a nightmare.</p>
<h2 id="HandleBody">Handle/Body Idiom</h2>
<p>One common usage of <code>shared_ptr</code> is to implement a handle/body (also called
pimpl) idiom which avoids exposing the body (implementation) in the header
file.</p>
<p>The <a href="example/shared_ptr_example2_test.cpp">shared_ptr_example2_test.cpp</a>
sample program includes a header file, <a href="example/shared_ptr_example2.hpp">shared_ptr_example2.hpp</a>,
which uses a <code>shared_ptr</code> to an incomplete type to hide the
implementation. The instantiation of member functions which require a complete
type occurs in the <a href="example/shared_ptr_example2.cpp">shared_ptr_example2.cpp</a>
implementation file. Note that there is no need for an explicit destructor.
Unlike <code>~scoped_ptr</code>, <code>~shared_ptr</code> does not require that <code>T</code> be a complete
type.</p>
<h2 id="ThreadSafety">Thread Safety</h2>
<p><code>shared_ptr</code> objects offer the same level of thread safety as
built-in types. A <code>shared_ptr</code> instance can be "read" (accessed
using only const operations) simultaneously by multiple threads. Different <code>shared_ptr</code>
instances can be "written to" (accessed using mutable operations such as <code>operator=
</code>or <code>reset</code>) simultaneously by multiple threads (even
when these instances are copies, and share the same reference count
underneath.)</p>
<p>Any other simultaneous accesses result in undefined behavior.</p>
<p>Examples:</p>
<pre>shared_ptr&lt;int&gt; p(new int(42));
//--- Example 1 ---
// thread A
shared_ptr&lt;int&gt; p2(p); // reads p
// thread B
shared_ptr&lt;int&gt; p3(p); // OK, multiple reads are safe
//--- Example 2 ---
// thread A
p.reset(new int(1912)); // writes p
// thread B
p2.reset(); // OK, writes p2
//--- Example 3 ---
// thread A
p = p3; // reads p3, writes p
// thread B
p3.reset(); // writes p3; undefined, simultaneous read/write
//--- Example 4 ---
// thread A
p3 = p2; // reads p2, writes p3
// thread B
// p2 goes out of scope: undefined, the destructor is considered a "write access"
//--- Example 5 ---
// thread A
p3.reset(new int(1));
// thread B
p3.reset(new int(2)); // undefined, multiple writes
</pre>
<p>&nbsp;</p>
<p>Starting with Boost release 1.33.0, <code>shared_ptr</code> uses a lock-free
implementation on most common platforms.</p>
<p>If your program is single-threaded and does not link to any libraries that might
have used <code>shared_ptr</code> in its default configuration, you can <code>
#define</code> the macro <code>BOOST_SP_DISABLE_THREADS</code> on a
project-wide basis to switch to ordinary non-atomic reference count updates.</p>
<p>(Defining <code>BOOST_SP_DISABLE_THREADS</code> in some, but not all,
translation units is technically a violation of the One Definition Rule and
undefined behavior. Nevertheless, the implementation attempts to do its best to
accommodate the request to use non-atomic updates in those translation units.
No guarantees, though.)</p>
<p>You can define the macro <code>BOOST_SP_USE_PTHREADS</code> to turn off the
lock-free platform-specific implementation and fall back to the generic
<code>pthread_mutex_t</code>-based code.</p>
<h2 id="FAQ">Frequently Asked Questions</h2>
<p><b>Q.</b> There are several variations of shared pointers, with different
tradeoffs; why does the smart pointer library supply only a single
implementation? It would be useful to be able to experiment with each type so
as to find the most suitable for the job at hand?</p>
<p>
<b>A.</b> An important goal of <code>shared_ptr</code> is to provide a
standard shared-ownership pointer. Having a single pointer type is important
for stable library interfaces, since different shared pointers typically cannot
interoperate, i.e. a reference counted pointer (used by library A) cannot share
ownership with a linked pointer (used by library B.)
</p>
<p><b>Q.</b> Why doesn't <code>shared_ptr</code> have template parameters supplying
traits or policies to allow extensive user customization?</p>
<p>
<b>A.</b> Parameterization discourages users. The <code>shared_ptr</code> template is
carefully crafted to meet common needs without extensive parameterization. Some
day a highly configurable smart pointer may be invented that is also very easy
to use and very hard to misuse. Until then, <code>shared_ptr</code> is the smart
pointer of choice for a wide range of applications. (Those interested in policy
based smart pointers should read <a href="http://www.awprofessional.com/bookstore/product.asp?isbn=0201704315&amp;rl=1">
Modern C++ Design</a> by Andrei Alexandrescu.)
</p>
<p><b>Q.</b> I am not convinced. Default parameters can be used where appropriate
to hide the complexity. Again, why not policies?</p>
<p>
<b>A.</b> Template parameters affect the type. See the answer to the first
question above.
</p>
<p><b>Q.</b> Why doesn't <code>shared_ptr</code> use a linked list implementation?</p>
<p>
<b>A.</b> A linked list implementation does not offer enough advantages to
offset the added cost of an extra pointer. See <a href="smarttests.htm">timings</a>
page. In addition, it is expensive to make a linked list implementation thread
safe.
</p>
<p><b>Q.</b> Why doesn't <code>shared_ptr</code> (or any of the other Boost smart
pointers) supply an automatic conversion to <code>T*</code>?</p>
<p>
<b>A.</b> Automatic conversion is believed to be too error prone.
</p>
<p><b>Q.</b> Why does <code>shared_ptr</code> supply <code>use_count()</code>?</p>
<p>
<b>A.</b> As an aid to writing test cases and debugging displays. One of the
progenitors had <code>use_count()</code>, and it was useful in tracking down bugs in a
complex project that turned out to have cyclic-dependencies.
</p>
<p><b>Q.</b> Why doesn't <code>shared_ptr</code> specify complexity requirements?</p>
<p>
<b>A.</b> Because complexity requirements limit implementors and complicate the
specification without apparent benefit to <code>shared_ptr</code> users. For example,
error-checking implementations might become non-conforming if they had to meet
stringent complexity requirements.
</p>
<p><b>Q.</b> Why doesn't <code>shared_ptr</code> provide a <code>release()</code> function?</p>
<p>
<b>A.</b> <code>shared_ptr</code> cannot give away ownership unless it's <code>unique()</code>
because the other copy will still destroy the object.</p>
<p>Consider:</p>
<blockquote><pre>shared_ptr&lt;int&gt; a(new int);
shared_ptr&lt;int&gt; b(a); // a.use_count() == b.use_count() == 2
int * p = a.release();
// Who owns p now? b will still call delete on it in its destructor.</pre>
</blockquote>
<p>Furthermore, the pointer returned by <code>release()</code> would be difficult
to deallocate reliably, as the source <code>shared_ptr</code> could have been created
with a custom deleter.
</p>
<p><b>Q.</b> Why is <code>operator-&gt;()</code> const, but its return value is a
non-const pointer to the element type?</p>
<p>
<b>A.</b> Shallow copy pointers, including raw pointers, typically don't
propagate constness. It makes little sense for them to do so, as you can always
obtain a non-const pointer from a const one and then proceed to modify the
object through it. <code>shared_ptr</code> is "as close to raw pointers as possible
but no closer".
</p>
<hr>
<p>$Date$</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002-2005, 2012, 2013 Peter Dimov. Distributed under the Boost Software License,
Version 1.0. See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a>
or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>.</small></p>
</body>
</html>

View File

@ -1,224 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Smart Pointers</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0">Smart Pointers</h1>
<p><a href="#Introduction">Introduction</a><br>
<a href="#common_requirements">Common Requirements</a><br>
<a href="#Exception_Safety">Exception Safety</a><br>
<a href="#Exception-specifications">Exception-specifications</a><br>
<a href="#History">History and Acknowledgements</a><br>
<a href="#References">References</a></p>
<h2><a name="Introduction">Introduction</a></h2>
<p>Smart pointers are objects which store pointers to dynamically allocated (heap)
objects. They behave much like built-in C++ pointers except that they
automatically delete the object pointed to at the appropriate time. Smart
pointers are particularly useful in the face of exceptions as they ensure
proper destruction of dynamically allocated objects. They can also be used to
keep track of dynamically allocated objects shared by multiple owners.</p>
<p>Conceptually, smart pointers are seen as owning the object pointed to, and thus
responsible for deletion of the object when it is no longer needed.</p>
<p>The smart pointer library provides six smart pointer class templates:</p>
<div align="left">
<table border="1" cellpadding="4" cellspacing="0">
<tr>
<td><a href="scoped_ptr.htm"><b>scoped_ptr</b></a></td>
<td><a href="../../boost/scoped_ptr.hpp">&lt;boost/scoped_ptr.hpp&gt;</a></td>
<td>Simple sole ownership of single objects. Noncopyable.</td>
</tr>
<tr>
<td><a href="scoped_array.htm"><b>scoped_array</b></a></td>
<td><a href="../../boost/scoped_array.hpp">&lt;boost/scoped_array.hpp&gt;</a></td>
<td>Simple sole ownership of arrays. Noncopyable.</td>
</tr>
<tr>
<td><a href="shared_ptr.htm"><b>shared_ptr</b></a></td>
<td><a href="../../boost/shared_ptr.hpp">&lt;boost/shared_ptr.hpp&gt;</a></td>
<td>Object ownership shared among multiple pointers.</td>
</tr>
<tr>
<td><a href="shared_array.htm"><b>shared_array</b></a></td>
<td><a href="../../boost/shared_array.hpp">&lt;boost/shared_array.hpp&gt;</a></td>
<td>Array ownership shared among multiple pointers.</td>
</tr>
<tr>
<td><a href="weak_ptr.htm"><b>weak_ptr</b></a></td>
<td><a href="../../boost/weak_ptr.hpp">&lt;boost/weak_ptr.hpp&gt;</a></td>
<td>Non-owning observers of an object owned by <b>shared_ptr</b>.</td>
</tr>
<tr>
<td><a href="intrusive_ptr.html"><b>intrusive_ptr</b></a></td>
<td><a href="../../boost/intrusive_ptr.hpp">&lt;boost/intrusive_ptr.hpp&gt;</a></td>
<td>Shared ownership of objects with an embedded reference count.</td>
</tr>
</table>
</div>
<p>These templates are designed to complement the <b>std::auto_ptr</b> template.</p>
<p>They are examples of the "resource acquisition is initialization" idiom
described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition,
Section 14.4, Resource Management.</p>
<p>Additionally, the smart pointer library provides efficient factory functions
for creating smart pointer objects:</p>
<div align="left">
<table border="1" cellpadding="4" cellspacing="0">
<tr>
<td><a href="make_shared.html"><b>make_shared, allocate_shared</b></a> for objects</td>
<td><a href="../../boost/make_shared.hpp">&lt;boost/make_shared.hpp&gt;</a></td>
<td>Efficient creation of <code>shared_ptr</code> objects.</td>
</tr>
<tr>
<td><a href="make_shared_array.html"><b>make_shared, allocate_shared</b></a> for arrays</td>
<td><a href="../../boost/make_shared.hpp">&lt;boost/make_shared.hpp&gt;</a></td>
<td>Efficient creation of <code>shared_ptr</code> arrays.</td>
</tr>
<tr>
<td><a href="make_unique.html"><b>make_unique</b></a></td>
<td><a href="../../boost/make_unique.hpp">&lt;boost/make_unique.hpp&gt;</a></td>
<td>Creation of <code>unique_ptr</code> objects and arrays.</td>
</tr>
</table>
</div>
<p>A test program, <a href="test/smart_ptr_test.cpp">smart_ptr_test.cpp</a>, is
provided to verify correct operation.</p>
<p>A page on <a href="compatibility.htm">compatibility</a> with older versions of
the Boost smart pointer library describes some of the changes since earlier
versions of the smart pointer implementation.</p>
<p>A page on <a href="smarttests.htm">smart pointer timings</a> will be of interest
to those curious about performance issues.</p>
<P>A page on <A href="sp_techniques.html">smart pointer programming techniques</A> lists
some advanced applications of <code>shared_ptr</code> and <code>weak_ptr</code>.</P>
<h2><a name="common_requirements">Common Requirements</a></h2>
<p>These smart pointer class templates have a template parameter, <b>T</b>, which
specifies the type of the object pointed to by the smart pointer. The behavior
of the smart pointer templates is undefined if the destructor or <b>operator delete</b>
for objects of type <b>T</b> throw exceptions.</p>
<p><b>T</b> may be an incomplete type at the point of smart pointer declaration.
Unless otherwise specified, it is required that <b>T</b> be a complete type at
points of smart pointer instantiation. Implementations are required to diagnose
(treat as an error) all violations of this requirement, including deletion of
an incomplete type. See the description of the <a href="../utility/utility.htm#checked_delete">
<b>checked_delete</b></a> function template.</p>
<P>Note that <STRONG>shared_ptr</STRONG> does not have this restriction, as most of
its member functions do not require <STRONG>T</STRONG> to be a complete type.</P>
<h3>Rationale</h3>
<p>The requirements on <b>T</b> are carefully crafted to maximize safety yet allow
handle-body (also called pimpl) and similar idioms. In these idioms a smart
pointer may appear in translation units where <b>T</b> is an incomplete type.
This separates interface from implementation and hides implementation from
translation units which merely use the interface. Examples described in the
documentation for specific smart pointers illustrate use of smart pointers in
these idioms.</p>
<p>Note that <b>scoped_ptr</b> requires that <b>T</b> be a complete type at
destruction time, but <b>shared_ptr</b> does not.</p>
<h2><a name="Exception_Safety">Exception Safety</a></h2>
<p>Several functions in these smart pointer classes are specified as having "no
effect" or "no effect except such-and-such" if an exception is thrown. This
means that when an exception is thrown by an object of one of these classes,
the entire program state remains the same as it was prior to the function call
which resulted in the exception being thrown. This amounts to a guarantee that
there are no detectable side effects. Other functions never throw exceptions.
The only exception ever thrown by functions which do throw (assuming <b>T</b> meets
the <a href="#common_requirements">common requirements</a>) is <b>std::bad_alloc</b>,
and that is thrown only by functions which are explicitly documented as
possibly throwing <b>std::bad_alloc</b>.</p>
<h2><a name="Exception-specifications">Exception-specifications</a></h2>
<p>Exception-specifications are not used; see <a href="http://www.boost.org/more/lib_guide.htm#Exception-specification">
exception-specification rationale</a>.</p>
<p>All the smart pointer templates contain member functions which can never throw
exceptions, because they neither throw exceptions themselves nor call other
functions which may throw exceptions. These members are indicated by a comment: <code>
// never throws</code>.
</p>
<p>Functions which destroy objects of the pointed to type are prohibited from
throwing exceptions by the <a href="#common_requirements">common requirements</a>.</p>
<h2><a name="History">History</a> and Acknowledgements</h2>
<p>February 2017. Glen Fernandes rewrote <b>allocate_shared</b>
and <b>make_shared</b> for arrays for a more optimal and more
maintainable implementation.</p>
<p>February 2014. Glen Fernandes updated overloads of <b>make_shared</b> and
<b>allocate_shared</b> to conform to the specification in C++ standard paper
<a href="#D&amp;F-14">[D&amp;F-14]</a>, and implemented <b>make_unique</b> for
arrays and objects. Peter Dimov and Glen Fernandes updated the scalar and
array implementations, respectively, to resolve C++ standard library defect
2070.</p>
<p>November 2012. Glen Fernandes provided implementations of <b>make_shared</b>
and <b>allocate_shared</b> for arrays. They achieve a single allocation for an
array that can be initialized with constructor arguments or initializer lists
as well as overloads for default initialization and no value initialization.
See the <a href="make_shared_array.html">make_shared and allocate_shared for
arrays</a> page for more information.</p>
<p>January 2002. Peter Dimov reworked all four classes, adding features, fixing
bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>.
See the <a href="compatibility.htm">compatibility</a> page for a summary of the
changes.</p>
<p>May 2001. Vladimir Prus suggested requiring a complete type on destruction.
Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman
Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and
others.</p>
<p>November 1999. Darin Adler provided <b>operator ==</b>, <b>operator !=</b>, and <b>std::swap</b>
and <b>std::less</b> specializations for shared types.</p>
<p>September 1999. Luis Coelho provided <b>shared_ptr::swap</b> and <b>shared_array::swap</b></p>
<p>May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a
number of suggestions resulting in numerous improvements.</p>
<p>October 1998. Beman Dawes proposed reviving the original semantics under the
names <b>safe_ptr</b> and <b>counted_ptr</b>, meeting of Per Andersson, Matt
Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar K&uuml;hl,
Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new
class names were finalized, it was decided that there was no need to exactly
follow the <b>std::auto_ptr</b> interface, and various function signatures and
semantics were finalized.</p>
<p>Over the next three months, several implementations were considered for <b>shared_ptr</b>,
and discussed on the <a href="http://www.boost.org">boost.org</a> mailing list.
The implementation questions revolved around the reference count which must be
kept, either attached to the pointed to object, or detached elsewhere. Each of
those variants have themselves two major variants:
<ul>
<li>
Direct detached: the shared_ptr contains a pointer to the object, and a pointer
to the count.
<li>
Indirect detached: the shared_ptr contains a pointer to a helper object, which
in turn contains a pointer to the object and the count.
<li>
Embedded attached: the count is a member of the object pointed to.
<li>
Placement attached: the count is attached via operator new manipulations.</li>
</ul>
<p>Each implementation technique has advantages and disadvantages. We went so far
as to run various timings of the direct and indirect approaches, and found that
at least on Intel Pentium chips there was very little measurable difference.
Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar
K&uuml;hl suggested an elegant partial template specialization technique to allow
users to choose which implementation they preferred, and that was also
experimented with.</p>
<p>But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage
users", and in the end we choose to supply only the direct implementation.</p>
<p>Summer, 1994. Greg Colvin proposed to the C++ Standards Committee classes named <b>auto_ptr</b>
and <b>counted_ptr</b> which were very similar to what we now call <b>scoped_ptr</b>
and <b>shared_ptr</b>. <a href="#Col-94">[Col-94]</a> In one of the very few
cases where the Library Working Group's recommendations were not followed by
the full committee, <b>counted_ptr</b> was rejected and surprising
transfer-of-ownership semantics were added to <b>auto_ptr</b>.</p>
<h2><a name="References">References</a></h2>
<p>[<a name="D&amp;F-14">D&amp;F-14</a>] Peter Dimov &amp; Glen Fernandes, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3870.html">
Extending make_shared to Support Arrays, Revision 1</a>, C++ committee document N3870,
January, 2014.</p>
<p>[<a name="Col-94">Col-94</a>] Gregory Colvin, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf">
Exception Safe Smart Pointers</a>, C++ committee document 94-168/N0555,
July, 1994.</p>
<p>[<a name="E&amp;D-94">E&amp;D-94</a>] John R. Ellis &amp; David L. Detlefs, <a href="http://www.usenix.org/publications/library/proceedings/c++94/full_papers/ellis.a">
Safe, Efficient Garbage Collection for C++</a>, Usenix Proceedings,
February, 1994. This paper includes an extensive discussion of weak pointers
and an extensive bibliography.</p>
<hr>
<p>$Date$</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Distributed under the Boost Software License, Version 1.0. See accompanying
file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or copy at
<A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

Binary file not shown.

View File

@ -1,542 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Smart Pointer Timings</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle" border="0">Smart Pointer Timings</h1>
<p>In late January 2000, Mark Borgerding put forward a suggestion to boost for
a new design of smart pointer whereby an intrusive doubly linked list is used
to join together all instances of smart pointers sharing a given raw pointer.
This allowed avoidance of the costly heap allocation of a reference count that
occurred in the initial construction of the then current version of boost::shared_ptr.
Of course, nothing is for free and the benefit here was gained at the expense
of increased size and more costly copy operations. A debate ensued on the boost
mailing list and the tests which this page describes were performed to provide
a guide for current and future investigations into smart pointer implementation
strategies.</p>
<p>Thanks are due to <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>,
Gavin Collings,
<a href="http://www.boost.org/people/greg_colvin.htm">Greg Colvin</a> and
<a href="http://www.boost.org/people/beman_dawes.html">Beman Dawes</a>
for test code and trial implementations, the final version of which can be found
in .zip format <a href="smarttest.zip">here</a>.</p>
<h2>Description</h2>
<p>Two tests were run: the first aimed to obtain timings for two basic individual
operations:</p>
<ol type="i">
<li> Initial construction from raw pointer.</li>
<li> An amortized copy operation consisting of half an assignment and half a
copy construction - designed to reflect average usage.</li>
</ol>
<p>The second attempted to gain more insight into normal usage by timing the fill
and sort algorithms for vectors and lists filled with the various smart pointers.</p>
<p>Five smart pointer implementation strategies were tested:</p>
<ol type="i">
<li>Counted pointer using a heap allocated reference count, this is referred
to as <b>simple counted</b>.</li>
<li>Counted pointer using a special purpose allocator for the reference count
- <b>special counted</b>.</li>
<li>Counted pointer using an intrusive reference count - <b>intrusive</b>.</li>
<li>Linked pointer as described above - <b>linked</b>.</li>
<li>Cyclic pointer, a counted implementation using a std::deque for allocation
with provision for weak pointers and garbage collection of cycles of pointers
- <b>cyclic</b>.</li>
</ol>
<p>on two compilers:</p>
<ol type="i">
<li>MSVC 6.0 service pack 3, using default release optimization mode (/O2 -
optimized for speed, no inlining of functions defined outside a class body
unless specified as inline).</li>
<li>gcc 2.95.2 using full optimization (-O3 -DNDEBUG).</li>
</ol>
<p>Additionally, generated pointer sizes (taking into account struct alignment)
were compared, as were generated code sizes for MSVC mainly by manual inspection
of generated assembly code - a necessity due to function inlining.</p>
<p>All tests were run on a PII-200 running Windows NT version 4.0</p>
<h2>&nbsp;</h2>
<h2>Operation Timing Test Results</h2>
<p>The following graphs show the overall time in nanoseconds to acquire a pointer
(default construction) perform n amortized copy operations on it and finally
release it. The initial allocation time for the contained pointer is not included,
although the time for it's deallocation is. The contained pointer pointed to
a trivial class, but for the inclusion of an intrusive reference count for the
benefit of the intrusive counted shared pointer. A dumb pointer (i.e. a smart
pointer that simply acquires and releases its contained pointer with no extra
overhead) and a raw pointer were also included for comparison.</p>
<table border="0" align="center">
<tr>
<td width="20" height="20">&nbsp;</td>
<td>&nbsp;</td>
<td width="20">&nbsp;</td>
</tr>
<tr>
<td width="20">&nbsp; </td>
<td><img src="msvcspeed.gif" width="560" height="355" alt="MSVC speed graph"></td>
<td width="20">&nbsp;</td>
</tr>
<tr>
<td height="20">&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><img src="gccspeed.gif" width="560" height="355" alt="GCC speed graph"></td>
<td>&nbsp;</td>
</tr>
<tr>
<td height="20">&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
<p>&nbsp;</p>
<p>Fitting straight lines to the above plots gives the following figures for initialization
and amortized copy operation for the two compilers (times in nanoseconds, errors
at two standard deviations) : -</p>
<p>&nbsp;</p>
<h4 align="center">MSVC</h4>
<table align="center" cellpadding="5" cellspacing="0" class="codetable" width="400">
<tr>
<th width="120">
<div align="right"></div>
</th>
<th class="codetabletop" width="120">
<div align="center">initialization</div>
</th>
<th class="codetabletop" width="120">copy operation</th>
</tr>
<tr>
<th class="codetableleft">
<div align="right">simple counted</div>
</th>
<td class="codetablecell" align="center">3000 +/- 170</td>
<td class="codetablecell" align="center">104 +/- 31</td>
</tr>
<tr>
<th class="codetableleft">
<div align="right">special counted</div>
</th>
<td class="codetablecell" align="center">1330 +/- 50</td>
<td class="codetablecell" align="center">85 +/- 9</td>
</tr>
<tr>
<th class="codetableleft">
<div align="right">intrusive</div>
</th>
<td class="codetablecell" align="center">1000 +/- 20</td>
<td class="codetablecell" align="center">71 +/- 3</td>
</tr>
<tr>
<th class="codetableleft" align="right">linked</th>
<td class="codetablecell" align="center">970 +/- 60</td>
<td class="codetablecell" align="center">136 +/- 10</td>
</tr>
<tr>
<th class="codetableleft" align="right">cyclic</th>
<td class="codetablecell" align="center">1290 +/- 70</td>
<td class="codetablecell" align="center">112 +/- 12</td>
</tr>
<tr>
<th class="codetableleft" align="right">dumb</th>
<td class="codetablecell" align="center">1020 +/- 20</td>
<td class="codetablecell" align="center">10 +/- 4</td>
</tr>
<tr>
<th class="codetableleft">
<div align="right">raw</div>
</th>
<td class="codetablecell" align="center">1038 +/- 30</td>
<td class="codetablecell" align="center">10 +/- 5</td>
</tr>
</table>
<h4 align="center">&nbsp;</h4>
<h4 align="center">GCC</h4>
<table align="center" cellpadding="5" cellspacing="0" class="codetable" width="400">
<tr>
<th width="120">
<div align="right"></div>
</th>
<th class="codetabletop" width="120">
<div align="center">initialization</div>
</th>
<th class="codetabletop" width="120">copy operation</th>
</tr>
<tr>
<th class="codetableleft">
<div align="right">simple counted</div>
</th>
<td class="codetablecell" align="center">4620 +/- 150</td>
<td class="codetablecell" align="center">301 +/- 28</td>
</tr>
<tr>
<th class="codetableleft">
<div align="right">special counted</div>
</th>
<td class="codetablecell" align="center">1990 +/- 40</td>
<td class="codetablecell" align="center">264 +/- 7</td>
</tr>
<tr>
<th class="codetableleft">
<div align="right">intrusive</div>
</th>
<td class="codetablecell" align="center">1590 +/- 70</td>
<td class="codetablecell" align="center">181 +/- 12</td>
</tr>
<tr>
<th class="codetableleft" align="right">linked</th>
<td class="codetablecell" align="center">1470 +/- 140</td>
<td class="codetablecell" align="center">345 +/- 26</td>
</tr>
<tr>
<th class="codetableleft" align="right">cyclic</th>
<td class="codetablecell" align="center">2180 +/- 100</td>
<td class="codetablecell" align="center">330 +/- 18</td>
</tr>
<tr>
<th class="codetableleft" align="right">dumb</th>
<td class="codetablecell" align="center">1590 +/- 70</td>
<td class="codetablecell" align="center">74 +/- 12</td>
</tr>
<tr>
<th class="codetableleft" align="right">
<div align="right">raw</div>
</th>
<td class="codetablecell" align="center">1430 +/- 60</td>
<td class="codetablecell" align="center">27 +/- 11</td>
</tr>
</table>
<p>Note that the above times include a certain amount of loop overhead etc. for
each operation. An estimate of the pure smart pointer operation time 'overhead'
can be obtained by subtracting the dumb or raw figure from the smart pointer
time of interest.</p>
<h3>Detail</h3>
<p>The test involved iterating a loop which creates raw pointers. These were then
shared among a varying number (set size) of smart pointers. A range of set sizes
was used and then a line fitted to get a linear relation with number of initializations
and copy-operations. A spreadsheet was used for the line fit, and to produce
the performance graphs above.</p>
<h2>&nbsp;</h2>
<h2>Container Test Results</h2>
<p>To gain some insight in to operation within real life programs, this test was
devised. Smart pointers were used to fill standard containers which were then
sorted.</p>
<p>In this case, the contained pointer pointed to a class which initializes a
private data member to a random value in its default constructor. This value
is used subsequently for the sort comparison test. The class also contains an
intrusive reference count for the benefit of the intrusive counted pointer.</p>
<p> All times are in seconds for 300,000 contained pointers.</p>
<h4 align="center">GCC</h4>
<table align="center" cellpadding="5" cellspacing="0" class="codetable" width="500">
<tr>
<th>&nbsp;</th>
<th class="codetabletop" colspan="2">vector</th>
<th class="codetabletop" colspan="2">list</th>
</tr>
<tr>
<th width="120">
<div align="right"></div>
</th>
<th class="codetabletop2" width="80">
<div align="center">fill</div>
</th>
<th class="codetabletop2" width="80">sort</th>
<th class="codetabletop2" width="80">fill</th>
<th class="codetabletop2" width="80">sort</th>
</tr>
<tr>
<th class="codetableleft">
<div align="right">simple counted</div>
</th>
<td class="codetablecell" align="center">46.54</td>
<td class="codetablecell" align="center">2.44</td>
<td class="codetablecell" align="center">47.09</td>
<td class="codetablecell" align="center">3.22</td>
</tr>
<tr>
<th class="codetableleft">
<div align="right">special counted</div>
</th>
<td class="codetablecell" align="center">14.02</td>
<td class="codetablecell" align="center">2.83</td>
<td class="codetablecell" align="center">7.28</td>
<td class="codetablecell" align="center">3.21</td>
</tr>
<tr>
<th class="codetableleft">
<div align="right">intrusive</div>
</th>
<td class="codetablecell" align="center">12.15</td>
<td class="codetablecell" align="center">1.91</td>
<td class="codetablecell" align="center">7.99</td>
<td class="codetablecell" align="center">3.08</td>
</tr>
<tr>
<th class="codetableleft" align="right">linked</th>
<td class="codetablecell" align="center">12.46</td>
<td class="codetablecell" align="center">2.32</td>
<td class="codetablecell" align="center">8.14</td>
<td class="codetablecell" align="center">3.27</td>
</tr>
<tr>
<th class="codetableleft" align="right">cyclic</th>
<td class="codetablecell" align="center">22.60</td>
<td class="codetablecell" align="center">3.19</td>
<td class="codetablecell" align="center">1.63</td>
<td class="codetablecell" align="center">3.18</td>
</tr>
<tr>
<th class="codetableleft" align="right">
<div align="right">raw</div>
</th>
<td class="codetablecell" align="center">11.81</td>
<td class="codetablecell" align="center">0.24</td>
<td class="codetablecell" align="center">27.51</td>
<td class="codetablecell" align="center">0.77</td>
</tr>
</table>
<p>&nbsp;</p>
<h4 align="center">MSVC</h4>
<table align="center" cellpadding="5" cellspacing="0" class="codetable" width="500">
<tr>
<th>&nbsp;</th>
<th class="codetabletop" colspan="2">vector</th>
<th class="codetabletop" colspan="2">list</th>
</tr>
<tr>
<th width="120">
<div align="right"></div>
</th>
<th class="codetabletop2" width="80">
<div align="center">fill</div>
</th>
<th class="codetabletop2" width="80">sort</th>
<th class="codetabletop2" width="80">fill</th>
<th class="codetabletop2" width="80">sort</th>
</tr>
<tr>
<th class="codetableleft">
<div align="right">simple counted</div>
</th>
<td class="codetablecell" align="center">1.83</td>
<td class="codetablecell" align="center">2.37</td>
<td class="codetablecell" align="center">1.86</td>
<td class="codetablecell" align="center">4.85</td>
</tr>
<tr>
<th class="codetableleft">
<div align="right">special counted</div>
</th>
<td class="codetablecell" align="center">1.04</td>
<td class="codetablecell" align="center">2.35</td>
<td class="codetablecell" align="center">1.38</td>
<td class="codetablecell" align="center">4.58</td>
</tr>
<tr>
<th class="codetableleft">
<div align="right">intrusive</div>
</th>
<td class="codetablecell" align="center">1.04</td>
<td class="codetablecell" align="center">1.84</td>
<td class="codetablecell" align="center">1.16</td>
<td class="codetablecell" align="center">4.29</td>
</tr>
<tr>
<th class="codetableleft" align="right">linked</th>
<td class="codetablecell" align="center">1.08</td>
<td class="codetablecell" align="center">2.00</td>
<td class="codetablecell" align="center">1.21</td>
<td class="codetablecell" align="center">4.33</td>
</tr>
<tr>
<th class="codetableleft" align="right">cyclic</th>
<td class="codetablecell" align="center">1.38</td>
<td class="codetablecell" align="center">2.84</td>
<td class="codetablecell" align="center">1.47</td>
<td class="codetablecell" align="center">4.73</td>
</tr>
<tr>
<th class="codetableleft" align="right">
<div align="right">raw</div>
</th>
<td class="codetablecell" align="center">0.67</td>
<td class="codetablecell" align="center">0.28</td>
<td class="codetablecell" align="center">1.24</td>
<td class="codetablecell" align="center">1.81</td>
</tr>
</table>
<p>&nbsp;</p>
<h2>Code Size</h2>
<p>The following code sizes were determined by inspection of generated code for
MSVC only. Sizes are given in the form N / M / I where:</p>
<ul type="circle">
<li> N is the instruction count of the operation</li>
<li>M is the size of the code in bytes</li>
<li>I determines whether generated code was inlined or not I = inline, O = &quot;outline&quot;</li>
</ul>
<p>&nbsp;</p>
<table align="center" cellpadding="5" cellspacing="0" class="codetable" width="570">
<tr>
<th height="28" width="140">
<div align="right"></div>
</th>
<th height="28" class="codetabletop" width="80">
<div align="center">ptr()</div>
</th>
<th height="28" class="codetabletop" width="80">ptr(p)</th>
<th height="28" class="codetabletop" width="80">ptr(ptr)</th>
<th height="28" class="codetabletop" width="80">op=()</th>
<th height="28" class="codetabletop" width="80">
<div align="center">~ptr()</div>
</th>
</tr>
<tr>
<th class="codetableleft">
<div align="right">simple counted</div>
</th>
<td class="codetablecell" align="center">38/110/O</td>
<td class="codetablecell" align="center">38/110/O</td>
<td class="codetablecell" align="center">9/23/I</td>
<td class="codetablecell" align="center">22/57/I</td>
<td class="codetablecell" align="center">17/40/I</td>
</tr>
<tr>
<th class="codetableleft">
<div align="right">special counted</div>
</th>
<td class="codetablecell" align="center"><font size="-1">50/141/O</font></td>
<td class="codetablecell" align="center"><font size="-1">50/141/O</font></td>
<td class="codetablecell" align="center"><font size="-1">9/23/I</font></td>
<td class="codetablecell" align="center"><font size="-1">23/64/I</font></td>
<td class="codetablecell" align="center"><font size="-1">13/38/I</font></td>
</tr>
<tr>
<th class="codetableleft">
<div align="right">intrusive</div>
</th>
<td class="codetablecell" align="center"><font size="-1">1/2/I</font></td>
<td class="codetablecell" align="center"><font size="-1">3/6/I</font></td>
<td class="codetablecell" align="center"><font size="-1">3/6/I</font></td>
<td class="codetablecell" align="center"><font size="-1">6/11/I</font></td>
<td class="codetablecell" align="center"><font size="-1">6/11/I</font></td>
</tr>
<tr>
<th class="codetableleft">
<div align="right">linked</div>
</th>
<td class="codetablecell" align="center"><font size="-1">5/19/I</font></td>
<td class="codetablecell" align="center"><font size="-1">5/15/I</font></td>
<td class="codetablecell" align="center"><font size="-1">10/30/I</font></td>
<td class="codetablecell" align="center"><font size="-1">27/59/I</font></td>
<td class="codetablecell" align="center"><font size="-1">14/38/I</font></td>
</tr>
</table>
<p>During the code inspection, a couple of minor points were noticed: -</p>
<ul>
<li>Function inlining was critical to performance.</li>
<li>For MSVC, at least, a &quot;delete 0&quot; caused execution of 11 assembly
instructions, including a function call. So in cases where performance is
at an absolute premium it can be worth inserting the extra manual test.</li>
</ul>
<h2>&nbsp;</h2>
<h2>Data Size</h2>
<p>The following smart pointer sizes were obtained in bytes</p>
<table align="center" cellpadding="5" cellspacing="0" class="codetable" width="270">
<tr>
<th height="28" width="150">
<div align="right"></div>
</th>
<th height="28" class="codetabletop" width="60">
<div align="center">MSVC</div>
</th>
<th height="28" class="codetabletop" width="60">
<div align="center">GCC</div>
</th>
</tr>
<tr>
<th class="codetableleft">
<div align="right">simple counted</div>
</th>
<td class="codetablecell">
<div align="center">8</div>
</td>
<td class="codetablecell">
<div align="center">8</div>
</td>
</tr>
<tr>
<th class="codetableleft">
<div align="right">special counted</div>
</th>
<td class="codetablecell">
<div align="center">8</div>
</td>
<td class="codetablecell">
<div align="center">12</div>
</td>
</tr>
<tr>
<th class="codetableleft">
<div align="right">intrusive</div>
</th>
<td class="codetablecell">
<div align="center">4</div>
</td>
<td class="codetablecell">
<div align="center">4</div>
</td>
</tr>
<tr>
<th class="codetableleft">
<div align="right">linked</div>
</th>
<td class="codetablecell">
<div align="center">12</div>
</td>
<td class="codetablecell">
<div align="center">12</div>
</td>
</tr>
<tr>
<th class="codetableleft">
<div align="right">cyclic</div>
</th>
<td class="codetablecell">
<div align="center">8</div>
</td>
<td class="codetablecell">
<div align="center">8</div>
</td>
</tr>
</table>
<h2>&nbsp;</h2>
<h2>Summary</h2>
<p>The timing results mainly speak for themselves: clearly an intrusive pointer
outperforms all others and a simple heap based counted pointer has poor performance
relative to other implementations. The selection of an optimal non-intrusive
smart pointer implementation is more application dependent, however. Where small
numbers of copies are expected, it is likely that the linked implementation
will be favoured. Conversely, for larger numbers of copies a counted pointer
with some type of special purpose allocator looks like a win. Other factors
to bear in mind are: -</p>
<ul>
<li>Deterministic individual, as opposed to amortized, operation time. This
weighs against any implementation depending on an allocator.</li>
<li>Multithreaded synchronization. This weighs against an implementation which
spreads its information as in the case of linked pointer.</li>
</ul>
<hr>
<p>$Date$</p>
<p>&copy; Copyright Gavin Collings 2000. Permission to copy, use, modify, sell
and distribute this document is granted provided this copyright notice appears in all
copies. This document is provided &quot;as is&quot; without express or implied warranty,
and with no claim as to its suitability for any purpose.</p>
</body>
</html>

View File

@ -1,765 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Smart Pointer Programming Techniques</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0">Smart Pointer Programming Techniques</h1>
<p><A href="#incomplete">Using incomplete classes for implementation hiding</A><br>
<A href="#pimpl">The "Pimpl" idiom</A><br>
<A href="#abstract">Using abstract classes for implementation hiding</A><br>
<A href="#preventing_delete">Preventing <code>delete px.get()</code></A><br>
<A href="#array">Using a <code>shared_ptr</code> to hold a pointer to an array</A><br>
<A href="#encapsulation">Encapsulating allocation details, wrapping factory
functions</A><br>
<A href="#static">Using a <code>shared_ptr</code> to hold a pointer to a statically
allocated object</A><br>
<A href="#com">Using a <code>shared_ptr</code> to hold a pointer to a COM object</A><br>
<A href="#intrusive">Using a <code>shared_ptr</code> to hold a pointer to an object
with an embedded reference count</A><br>
<A href="#another_sp">Using a <code>shared_ptr</code> to hold another shared
ownership smart pointer</A><br>
<A href="#from_raw">Obtaining a <code>shared_ptr</code> from a raw pointer</A><br>
<A href="#in_constructor">Obtaining a <code>shared_ptr</code> (<code>weak_ptr</code>)
to <code>this</code> in a constructor</A><br>
<A href="#from_this">Obtaining a <code>shared_ptr</code> to <code>this</code></A><br>
<A href="#handle">Using <code>shared_ptr</code> as a smart counted handle</A><br>
<A href="#on_block_exit">Using <code>shared_ptr</code> to execute code on block
exit</A><br>
<A href="#pvoid">Using <code>shared_ptr&lt;void&gt;</code> to hold an arbitrary
object</A><br>
<A href="#extra_data">Associating arbitrary data with heterogeneous <code>shared_ptr</code>
instances</A><br>
<A href="#as_lock">Using <code>shared_ptr</code> as a CopyConstructible mutex lock</A><br>
<A href="#wrapper">Using <code>shared_ptr</code> to wrap member function calls</A><br>
<A href="#delayed">Delayed deallocation</A><br>
<A href="#weak_without_shared">Weak pointers to objects not managed by a <code>shared_ptr</code></A><br>
</p>
<h2><A name="incomplete">Using incomplete classes for implementation hiding</A></h2>
<p>A proven technique (that works in C, too) for separating interface from
implementation is to use a pointer to an incomplete class as an opaque handle:</p>
<pre>class FILE;
FILE * fopen(char const * name, char const * mode);
void fread(FILE * f, void * data, size_t size);
void fclose(FILE * f);
</pre>
<p>It is possible to express the above interface using <code>shared_ptr</code>,
eliminating the need to manually call <code>fclose</code>:</p>
<pre>class FILE;
shared_ptr&lt;FILE&gt; fopen(char const * name, char const * mode);
void fread(shared_ptr&lt;FILE&gt; f, void * data, size_t size);
</pre>
<p>This technique relies on <code>shared_ptr</code>'s ability to execute a custom
deleter, eliminating the explicit call to <code>fclose</code>, and on the fact
that <code>shared_ptr&lt;X&gt;</code> can be copied and destroyed when <code>X</code>
is incomplete.</p>
<h2><A name="pimpl">The "Pimpl" idiom</A></h2>
<p>A C++ specific variation of the incomplete class pattern is the "Pimpl" idiom.
The incomplete class is not exposed to the user; it is hidden behind a
forwarding facade. <code>shared_ptr</code> can be used to implement a "Pimpl":</p>
<pre>// file.hpp:
class file
{
private:
class impl;
shared_ptr&lt;impl&gt; pimpl_;
public:
file(char const * name, char const * mode);
// compiler generated members are fine and useful
void read(void * data, size_t size);
};
</pre>
<pre>// file.cpp:
#include "file.hpp"
class file::impl
{
private:
impl(impl const &amp;);
impl &amp; operator=(impl const &amp;);
// private data
public:
impl(char const * name, char const * mode) { ... }
~impl() { ... }
void read(void * data, size_t size) { ... }
};
file::file(char const * name, char const * mode): pimpl_(new impl(name, mode))
{
}
void file::read(void * data, size_t size)
{
pimpl_-&gt;read(data, size);
}
</pre>
<p>The key thing to note here is that the compiler-generated copy constructor,
assignment operator, and destructor all have a sensible meaning. As a result, <code>
file</code> is <code>CopyConstructible</code> and <code>Assignable</code>,
allowing its use in standard containers.</p>
<h2><A name="abstract">Using abstract classes for implementation hiding</A></h2>
<p>Another widely used C++ idiom for separating inteface and implementation is to
use abstract base classes and factory functions. The abstract classes are
sometimes called "interfaces" and the pattern is known as "interface-based
programming". Again, <code>shared_ptr</code> can be used as the return type of
the factory functions:</p>
<pre>// X.hpp:
class X
{
public:
virtual void f() = 0;
virtual void g() = 0;
protected:
~X() {}
};
shared_ptr&lt;X&gt; createX();
</pre>
<pre>-- X.cpp:
class X_impl: public X
{
private:
X_impl(X_impl const &amp;);
X_impl &amp; operator=(X_impl const &amp;);
public:
virtual void f()
{
// ...
}
virtual void g()
{
// ...
}
};
shared_ptr&lt;X&gt; createX()
{
shared_ptr&lt;X&gt; px(new X_impl);
return px;
}
</pre>
<p>A key property of shared_ptr is that the allocation, construction, deallocation,
and destruction details are captured at the point of construction, inside the
factory function. Note the protected and nonvirtual destructor in the example
above. The client code cannot, and does not need to, delete a pointer to <code>X</code>;
the <code>shared_ptr&lt;X&gt;</code> instance returned from <code>createX</code>
will correctly call <code>~X_impl</code>.</p>
<h2><A name="preventing_delete">Preventing <code>delete px.get()</code></A></h2>
<p>It is often desirable to prevent client code from deleting a pointer that is
being managed by <code>shared_ptr</code>. The previous technique showed one
possible approach, using a protected destructor. Another alternative is to use
a private deleter:</p>
<pre>class X
{
private:
~X();
class deleter;
friend class deleter;
class deleter
{
public:
void operator()(X * p) { delete p; }
};
public:
static shared_ptr&lt;X&gt; create()
{
shared_ptr&lt;X&gt; px(new X, X::deleter());
return px;
}
};
</pre>
<h2><A name="array">Using a <code>shared_ptr</code> to hold a pointer to an array</A></h2>
<p>A <code>shared_ptr</code> can be used to hold a pointer to an array allocated
with <code>new[]</code>:</p>
<pre>shared_ptr&lt;X&gt; px(new X[1], <A href="../utility/checked_delete.html" >checked_array_deleter</A>&lt;X&gt;());
</pre>
<p>Note, however, that <code><A href="shared_array.htm">shared_array</A></code> is
often preferable, if this is an option. It has an array-specific interface,
without <code>operator*</code> and <code>operator-&gt;</code>, and does not
allow pointer conversions.</p>
<h2><A name="encapsulation">Encapsulating allocation details, wrapping factory
functions</A></h2>
<p><code>shared_ptr</code> can be used in creating C++ wrappers over existing C
style library interfaces that return raw pointers from their factory functions
to encapsulate allocation details. As an example, consider this interface,
where <code>CreateX</code> might allocate <code>X</code> from its own private
heap, <code>~X</code> may be inaccessible, or <code>X</code> may be incomplete:</p>
<pre>X * CreateX();
void DestroyX(X *);
</pre>
<p>The only way to reliably destroy a pointer returned by <code>CreateX</code> is
to call <code>DestroyX</code>.</p>
<P>Here is how a <code>shared_ptr</code>-based wrapper may look like:</P>
<pre>shared_ptr&lt;X&gt; createX()
{
shared_ptr&lt;X&gt; px(CreateX(), DestroyX);
return px;
}
</pre>
<p>Client code that calls <code>createX</code> still does not need to know how the
object has been allocated, but now the destruction is automatic.</p>
<h2><A name="static">Using a <code>shared_ptr</code> to hold a pointer to a statically
allocated object</A></h2>
<p>Sometimes it is desirable to create a <code>shared_ptr</code> to an already
existing object, so that the <code>shared_ptr</code> does not attempt to
destroy the object when there are no more references left. As an example, the
factory function:</p>
<pre>shared_ptr&lt;X&gt; createX();
</pre>
<p>in certain situations may need to return a pointer to a statically allocated <code>X</code>
instance.</p>
<P>The solution is to use a custom deleter that does nothing:</P>
<pre>struct null_deleter
{
void operator()(void const *) const
{
}
};
static X x;
shared_ptr&lt;X&gt; createX()
{
shared_ptr&lt;X&gt; px(&amp;x, null_deleter());
return px;
}
</pre>
<p>The same technique works for any object known to outlive the pointer.</p>
<h2><A name="com">Using a <code>shared_ptr</code> to hold a pointer to a COM Object</A></h2>
<p>Background: COM objects have an embedded reference count and two member
functions that manipulate it. <code>AddRef()</code> increments the count. <code>Release()</code>
decrements the count and destroys itself when the count drops to zero.</p>
<P>It is possible to hold a pointer to a COM object in a <code>shared_ptr</code>:</P>
<pre>shared_ptr&lt;IWhatever&gt; make_shared_from_COM(IWhatever * p)
{
p-&gt;AddRef();
shared_ptr&lt;IWhatever&gt; pw(p, <A href="../bind/mem_fn.html" >mem_fn</A>(&amp;IWhatever::Release));
return pw;
}
</pre>
<p>Note, however, that <code>shared_ptr</code> copies created from <code>pw</code> will
not "register" in the embedded count of the COM object; they will share the
single reference created in <code>make_shared_from_COM</code>. Weak pointers
created from <code>pw</code> will be invalidated when the last <code>shared_ptr</code>
is destroyed, regardless of whether the COM object itself is still alive.</p>
<P>As <A href="../bind/mem_fn.html#Q3">explained</A> in the <code>mem_fn</code> documentation,
you need to <A href="../bind/mem_fn.html#stdcall">#define
BOOST_MEM_FN_ENABLE_STDCALL</A> first.</P>
<h2><A name="intrusive">Using a <code>shared_ptr</code> to hold a pointer to an object
with an embedded reference count</A></h2>
<p>This is a generalization of the above technique. The example assumes that the
object implements the two functions required by <code><A href="intrusive_ptr.html">intrusive_ptr</A></code>,
<code>intrusive_ptr_add_ref</code> and <code>intrusive_ptr_release</code>:</p>
<pre>template&lt;class T&gt; struct intrusive_deleter
{
void operator()(T * p)
{
if(p) intrusive_ptr_release(p);
}
};
shared_ptr&lt;X&gt; make_shared_from_intrusive(X * p)
{
if(p) intrusive_ptr_add_ref(p);
shared_ptr&lt;X&gt; px(p, intrusive_deleter&lt;X&gt;());
return px;
}
</pre>
<h2><A name="another_sp">Using a <code>shared_ptr</code> to hold another shared
ownership smart pointer</A></h2>
<p>One of the design goals of <code>shared_ptr</code> is to be used in library
interfaces. It is possible to encounter a situation where a library takes a <code>shared_ptr</code>
argument, but the object at hand is being managed by a different reference
counted or linked smart pointer.</p>
<P>It is possible to exploit <code>shared_ptr</code>'s custom deleter feature to
wrap this existing smart pointer behind a <code>shared_ptr</code> facade:</P>
<pre>template&lt;class P&gt; struct smart_pointer_deleter
{
private:
P p_;
public:
smart_pointer_deleter(P const &amp; p): p_(p)
{
}
void operator()(void const *)
{
p_.reset();
}
P const &amp; get() const
{
return p_;
}
};
shared_ptr&lt;X&gt; make_shared_from_another(another_ptr&lt;X&gt; qx)
{
shared_ptr&lt;X&gt; px(qx.get(), smart_pointer_deleter&lt; another_ptr&lt;X&gt; &gt;(qx));
return px;
}
</pre>
<p>One subtle point is that deleters are not allowed to throw exceptions, and the
above example as written assumes that <code>p_.reset()</code> doesn't throw. If
this is not the case, <code>p_.reset()</code> should be wrapped in a <code>try {}
catch(...) {}</code> block that ignores exceptions. In the (usually
unlikely) event when an exception is thrown and ignored, <code>p_</code> will
be released when the lifetime of the deleter ends. This happens when all
references, including weak pointers, are destroyed or reset.</p>
<P>Another twist is that it is possible, given the above <code>shared_ptr</code> instance,
to recover the original smart pointer, using <code><A href="shared_ptr.htm#get_deleter">
get_deleter</A></code>:</P>
<pre>void extract_another_from_shared(shared_ptr&lt;X&gt; px)
{
typedef smart_pointer_deleter&lt; another_ptr&lt;X&gt; &gt; deleter;
if(deleter const * pd = get_deleter&lt;deleter&gt;(px))
{
another_ptr&lt;X&gt; qx = pd-&gt;get();
}
else
{
// not one of ours
}
}
</pre>
<h2><A name="from_raw">Obtaining a <code>shared_ptr</code> from a raw pointer</A></h2>
<p>Sometimes it is necessary to obtain a <code>shared_ptr</code> given a raw
pointer to an object that is already managed by another <code>shared_ptr</code>
instance. Example:</p>
<pre>void f(X * p)
{
shared_ptr&lt;X&gt; px(<i>???</i>);
}
</pre>
<p>Inside <code>f</code>, we'd like to create a <code>shared_ptr</code> to <code>*p</code>.</p>
<P>In the general case, this problem has no solution. One approach is to modify <code>f</code>
to take a <code>shared_ptr</code>, if possible:</P>
<pre>void f(shared_ptr&lt;X&gt; px);
</pre>
<p>The same transformation can be used for nonvirtual member functions, to convert
the implicit <code>this</code>:</p>
<pre>void X::f(int m);
</pre>
<p>would become a free function with a <code>shared_ptr</code> first argument:</p>
<pre>void f(shared_ptr&lt;X&gt; this_, int m);
</pre>
<p>If <code>f</code> cannot be changed, but <code>X</code> uses intrusive counting,
use <code><A href="#intrusive">make_shared_from_intrusive</A></code> described
above. Or, if it's known that the <code>shared_ptr</code> created in <code>f</code>
will never outlive the object, use <A href="#static">a null deleter</A>.</p>
<h2><A name="in_constructor">Obtaining a <code>shared_ptr</code> (<code>weak_ptr</code>)
to <code>this</code> in a constructor</A></h2>
<p>Some designs require objects to register themselves on construction with a
central authority. When the registration routines take a shared_ptr, this leads
to the question how could a constructor obtain a shared_ptr to this:</p>
<pre>class X
{
public:
X()
{
shared_ptr&lt;X&gt; this_(<i>???</i>);
}
};
</pre>
<p>In the general case, the problem cannot be solved. The <code>X</code> instance
being constructed can be an automatic variable or a static variable; it can be
created on the heap:</p>
<pre>shared_ptr&lt;X&gt; px(new X);</pre>
<P>but at construction time, <code>px</code> does not exist yet, and it is
impossible to create another <code>shared_ptr</code> instance that shares
ownership with it.</P>
<P>Depending on context, if the inner <code>shared_ptr</code> <code>this_</code> doesn't
need to keep the object alive, use a <code>null_deleter</code> as explained <A href="#static">
here</A> and <A href="#weak_without_shared">here</A>. If <code>X</code> is
supposed to always live on the heap, and be managed by a <code>shared_ptr</code>,
use a static factory function:</P>
<pre>class X
{
private:
X() { ... }
public:
static shared_ptr&lt;X&gt; create()
{
shared_ptr&lt;X&gt; px(new X);
// use px as 'this_'
return px;
}
};
</pre>
<h2><A name="from_this">Obtaining a <code>shared_ptr</code> to <code>this</code></A></h2>
<p>Sometimes it is needed to obtain a <code>shared_ptr</code> from <code>this</code>
in a virtual member function under the assumption that <code>this</code> is
already managed by a <code>shared_ptr</code>. The transformations <A href="#from_raw">
described in the previous technique</A> cannot be applied.</p>
<P>A typical example:</P>
<pre>class X
{
public:
virtual void f() = 0;
protected:
~X() {}
};
class Y
{
public:
virtual shared_ptr&lt;X&gt; getX() = 0;
protected:
~Y() {}
};
// --
class impl: public X, public Y
{
public:
impl() { ... }
virtual void f() { ... }
virtual shared_ptr&lt;X&gt; getX()
{
shared_ptr&lt;X&gt; px(<i>???</i>);
return px;
}
};
</pre>
<p>The solution is to keep a weak pointer to <code>this</code> as a member in <code>impl</code>:</p>
<pre>class impl: public X, public Y
{
private:
weak_ptr&lt;impl&gt; weak_this;
impl(impl const &amp;);
impl &amp; operator=(impl const &amp;);
impl() { ... }
public:
static shared_ptr&lt;impl&gt; create()
{
shared_ptr&lt;impl&gt; pi(new impl);
pi-&gt;weak_this = pi;
return pi;
}
virtual void f() { ... }
virtual shared_ptr&lt;X&gt; getX()
{
shared_ptr&lt;X&gt; px(weak_this);
return px;
}
};
</pre>
<p>The library now includes a helper class template <code><A href="enable_shared_from_this.html">
enable_shared_from_this</A></code> that can be used to encapsulate the
solution:</p>
<pre>class impl: public X, public Y, public enable_shared_from_this&lt;impl&gt;
{
public:
impl(impl const &amp;);
impl &amp; operator=(impl const &amp;);
public:
virtual void f() { ... }
virtual shared_ptr&lt;X&gt; getX()
{
return shared_from_this();
}
}
</pre>
<p>Note that you no longer need to manually initialize the <code>weak_ptr</code> member
in <code><A href="enable_shared_from_this.html">enable_shared_from_this</A></code>.
Constructing a <code>shared_ptr</code> to <code>impl</code> takes care of that.</p>
<h2><A name="handle">Using <code>shared_ptr</code> as a smart counted handle</A></h2>
<p>Some library interfaces use opaque handles, a variation of the <A href="#incomplete">
incomplete class technique</A> described above. An example:</p>
<pre>typedef void * HANDLE;
HANDLE CreateProcess();
void CloseHandle(HANDLE);
</pre>
<p>Instead of a raw pointer, it is possible to use <code>shared_ptr</code> as the
handle and get reference counting and automatic resource management for free:</p>
<pre>typedef shared_ptr&lt;void&gt; handle;
handle createProcess()
{
shared_ptr&lt;void&gt; pv(CreateProcess(), CloseHandle);
return pv;
}
</pre>
<h2><A name="on_block_exit">Using <code>shared_ptr</code> to execute code on block exit</A></h2>
<p><code>shared_ptr&lt;void&gt;</code> can automatically execute cleanup code when
control leaves a scope.</p>
<UL>
<LI>
Executing <code>f(p)</code>, where <code>p</code> is a pointer:</LI></UL>
<pre> shared_ptr&lt;void&gt; guard(p, f);
</pre>
<UL>
<LI>
Executing arbitrary code: <code>f(x, y)</code>:</LI></UL>
<pre> shared_ptr&lt;void&gt; guard(static_cast&lt;void*&gt;(0), <A href="../bind/bind.html" >bind</A>(f, x, y));
</pre>
<P>For a more thorough treatment, see the article "Simplify Your Exception-Safe
Code" by Andrei Alexandrescu and Petru Marginean, available online at <A href="http://www.cuj.com/experts/1812/alexandr.htm?topic=experts">
http://www.cuj.com/experts/1812/alexandr.htm?topic=experts</A>.</P>
<h2><A name="pvoid">Using <code>shared_ptr&lt;void&gt;</code> to hold an arbitrary
object</A></h2>
<p><code>shared_ptr&lt;void&gt;</code> can act as a generic object pointer similar
to <code>void*</code>. When a <code>shared_ptr&lt;void&gt;</code> instance
constructed as:</p>
<pre> shared_ptr&lt;void&gt; pv(new X);
</pre>
<p>is destroyed, it will correctly dispose of the <code>X</code> object by
executing <code>~X</code>.</p>
<p>This propery can be used in much the same manner as a raw <code>void*</code> is
used to temporarily strip type information from an object pointer. A <code>shared_ptr&lt;void&gt;</code>
can later be cast back to the correct type by using <code><A href="shared_ptr.htm#static_pointer_cast">
static_pointer_cast</A></code>.</p>
<h2><A name="extra_data">Associating arbitrary data with heterogeneous <code>shared_ptr</code>
instances</A></h2>
<p><code>shared_ptr</code> and <code>weak_ptr</code> support <code>operator&lt;</code>
comparisons required by standard associative containers such as <code>std::map</code>.
This can be used to non-intrusively associate arbitrary data with objects
managed by <code>shared_ptr</code>:</p>
<pre>typedef int Data;
std::map&lt; shared_ptr&lt;void&gt;, Data &gt; userData;
// or std::map&lt; weak_ptr&lt;void&gt;, Data &gt; userData; to not affect the lifetime
shared_ptr&lt;X&gt; px(new X);
shared_ptr&lt;int&gt; pi(new int(3));
userData[px] = 42;
userData[pi] = 91;
</pre>
<h2><A name="as_lock">Using <code>shared_ptr</code> as a CopyConstructible mutex lock</A></h2>
<p>Sometimes it's necessary to return a mutex lock from a function, and a
noncopyable lock cannot be returned by value. It is possible to use <code>shared_ptr</code>
as a mutex lock:</p>
<pre>class mutex
{
public:
void lock();
void unlock();
};
shared_ptr&lt;mutex&gt; lock(mutex &amp; m)
{
m.lock();
return shared_ptr&lt;mutex&gt;(&amp;m, mem_fn(&amp;mutex::unlock));
}
</pre>
<p>Better yet, the <code>shared_ptr</code> instance acting as a lock can be
encapsulated in a dedicated <code>shared_lock</code> class:</p>
<pre>class shared_lock
{
private:
shared_ptr&lt;void&gt; pv;
public:
template&lt;class Mutex&gt; explicit shared_lock(Mutex &amp; m): pv((m.lock(), &amp;m), mem_fn(&amp;Mutex::unlock)) {}
};
</pre>
<p><code>shared_lock</code> can now be used as:</p>
<pre> shared_lock lock(m);
</pre>
<p>Note that <code>shared_lock</code> is not templated on the mutex type, thanks to <code>
shared_ptr&lt;void&gt;</code>'s ability to hide type information.</p>
<h2><A name="wrapper">Using <code>shared_ptr</code> to wrap member function calls</A></h2>
<p><code>shared_ptr</code> implements the ownership semantics required from the <code>Wrap</code>/<code>CallProxy</code>
scheme described in Bjarne Stroustrup's article "Wrapping C++ Member Function
Calls" (available online at <A href="http://www.stroustrup.com/wrapper.pdf">http://www.stroustrup.com/wrapper.pdf</A>).
An implementation is given below:</p>
<pre>template&lt;class T&gt; class pointer
{
private:
T * p_;
public:
explicit pointer(T * p): p_(p)
{
}
shared_ptr&lt;T&gt; operator-&gt;() const
{
p_-&gt;prefix();
return shared_ptr&lt;T&gt;(p_, <A href="../bind/mem_fn.html" >mem_fn</A>(&amp;T::suffix));
}
};
class X
{
private:
void prefix();
void suffix();
friend class pointer&lt;X&gt;;
public:
void f();
void g();
};
int main()
{
X x;
pointer&lt;X&gt; px(&amp;x);
px-&gt;f();
px-&gt;g();
}
</pre>
<h2><A name="delayed">Delayed deallocation</A></h2>
<p>In some situations, a single <code>px.reset()</code> can trigger an expensive
deallocation in a performance-critical region:</p>
<pre>class X; // ~X is expensive
class Y
{
shared_ptr&lt;X&gt; px;
public:
void f()
{
px.reset();
}
};
</pre>
<p>The solution is to postpone the potential deallocation by moving <code>px</code>
to a dedicated free list that can be periodically emptied when performance and
response times are not an issue:</p>
<pre>vector&lt; shared_ptr&lt;void&gt; &gt; free_list;
class Y
{
shared_ptr&lt;X&gt; px;
public:
void f()
{
free_list.push_back(px);
px.reset();
}
};
// periodically invoke free_list.clear() when convenient
</pre>
<p>Another variation is to move the free list logic to the construction point by
using a delayed deleter:</p>
<pre>struct delayed_deleter
{
template&lt;class T&gt; void operator()(T * p)
{
try
{
shared_ptr&lt;void&gt; pv(p);
free_list.push_back(pv);
}
catch(...)
{
}
}
};
</pre>
<h2><A name="weak_without_shared">Weak pointers to objects not managed by a <code>shared_ptr</code></A></h2>
<p>Make the object hold a <code>shared_ptr</code> to itself, using a <code>null_deleter</code>:</p>
<pre>class X
{
private:
shared_ptr&lt;X&gt; this_;
int i_;
public:
explicit X(int i): this_(this, null_deleter()), i_(i)
{
}
// repeat in all constructors (including the copy constructor!)
X(X const &amp; rhs): this_(this, null_deleter()), i_(rhs.i_)
{
}
// do not forget to not assign this_ in the copy assignment
X &amp; operator=(X const &amp; rhs)
{
i_ = rhs.i_;
}
weak_ptr&lt;X&gt; get_weak_ptr() const { return this_; }
};
</pre>
<p>When the object's lifetime ends, <code>X::this_</code> will be destroyed, and
all weak pointers will automatically expire.</p>
<hr>
<p>$Date$</p>
<p><small>Copyright &copy; 2003 Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>

View File

@ -1,240 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>weak_ptr</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0">weak_ptr class template</h1>
<p><A href="#Introduction">Introduction</A><br>
<A href="#Synopsis">Synopsis</A><br>
<A href="#Members">Members</A><br>
<A href="#functions">Free Functions</A><br>
<A href="#FAQ">Frequently Asked Questions</A>
</p>
<h2><a name="Introduction">Introduction</a></h2>
<p>The <b>weak_ptr</b> class template stores a "weak reference" to an object that's
already managed by a <b>shared_ptr</b>. To access the object, a <STRONG>weak_ptr</STRONG>
can be converted to a <STRONG>shared_ptr</STRONG> using <A href="shared_ptr.htm#constructors">
the <STRONG>shared_ptr</STRONG> constructor</A> or the member function <STRONG><A href="#lock">
lock</A></STRONG>. When the last <b>shared_ptr</b> to the object goes
away and the object is deleted, the attempt to obtain a <STRONG>shared_ptr</STRONG>
from the <b>weak_ptr</b> instances that refer to the deleted object will fail:
the constructor will throw an exception of type <STRONG>boost::bad_weak_ptr</STRONG>,
and <STRONG>weak_ptr::lock</STRONG> will return an <EM>empty</EM> <STRONG>shared_ptr</STRONG>.</p>
<p>Every <b>weak_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>weak_ptr</b> works with the
standard library's associative containers.</p>
<P><STRONG>weak_ptr</STRONG> operations never throw&nbsp;exceptions.</P>
<p>The class template is parameterized on <b>T</b>, the type of the object pointed
to.</p>
<P>Compared to <STRONG>shared_ptr</STRONG>, <STRONG>weak_ptr</STRONG> provides a
very limited subset of operations since accessing its stored pointer is often
dangerous in multithreaded programs, and sometimes unsafe even within a single
thread (that is, it may invoke undefined behavior.) Pretend for a moment that <b>weak_ptr</b>
has a <b>get</b> member function that returns a raw pointer, and consider this
innocent piece of code:</P>
<pre>shared_ptr&lt;int&gt; p(new int(5));
weak_ptr&lt;int&gt; q(p);
// some time later
if(int * r = q.get())
{
// use *r
}
</pre>
<P>Imagine that after the <STRONG>if</STRONG>, but immediately before <STRONG>r</STRONG>
is used, another thread executes the statement <code>p.reset()</code>. Now <STRONG>r</STRONG>
is a dangling pointer.</P>
<P>The solution to this problem is to create a temporary <STRONG>shared_ptr</STRONG>
from <STRONG>q</STRONG>:</P>
<pre>shared_ptr&lt;int&gt; p(new int(5));
weak_ptr&lt;int&gt; q(p);
// some time later
if(shared_ptr&lt;int&gt; r = q.<A href="#lock" >lock</A>())
{
// use *r
}
</pre>
<p>Now <STRONG>r</STRONG> holds a reference to the object that was pointed by <STRONG>q</STRONG>.
Even if <code>p.reset()</code> is executed in another thread, the object will
stay alive until <STRONG>r</STRONG> goes out of scope or is reset. By obtaining
a <STRONG>shared_ptr</STRONG> to the object, we have effectively locked it
against destruction.</p>
<h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost {
template&lt;class T&gt; class weak_ptr {
public:
typedef T <A href="#element_type" >element_type</A>;
<A href="#default-constructor" >weak_ptr</A>();
template&lt;class Y&gt; <A href="#constructors" >weak_ptr</A>(shared_ptr&lt;Y&gt; const &amp; r);
<A href="#constructors" >weak_ptr</A>(weak_ptr const &amp; r);
template&lt;class Y&gt; <A href="#constructors" >weak_ptr</A>(weak_ptr&lt;Y&gt; const &amp; r);
<A href="#destructor" >~weak_ptr</A>();
weak_ptr &amp; <A href="#assignment" >operator=</A>(weak_ptr const &amp; r);
template&lt;class Y&gt; weak_ptr &amp; <A href="#assignment" >operator=</A>(weak_ptr&lt;Y&gt; const &amp; r);
template&lt;class Y&gt; weak_ptr &amp; <A href="#assignment" >operator=</A>(shared_ptr&lt;Y&gt; const &amp; r);
long <A href="#use_count" >use_count</A>() const;
bool <A href="#expired" >expired</A>() const;
shared_ptr&lt;T&gt; <A href="#lock" >lock</A>() const;
void <A href="#reset" >reset</A>();
void <A href="#swap" >swap</A>(weak_ptr&lt;T&gt; &amp; b);
};
template&lt;class T, class U&gt;
bool <A href="#comparison" >operator&lt;</A>(weak_ptr&lt;T&gt; const &amp; a, weak_ptr&lt;U&gt; const &amp; b);
template&lt;class T&gt;
void <A href="#free-swap" >swap</A>(weak_ptr&lt;T&gt; &amp; a, weak_ptr&lt;T&gt; &amp; b);
}
</pre>
<h2><a name="Members">Members</a></h2>
<h3><a name="element_type">element_type</a></h3>
<pre>typedef T element_type;</pre>
<blockquote>
<p>Provides the type of the template parameter T.</p>
</blockquote>
<h3><a name="constructors">constructors</a></h3>
<pre><a name="default-constructor">weak_ptr();</a></pre>
<blockquote>
<p><b>Effects:</b> Constructs an <EM>empty</EM> <b>weak_ptr</b>.</p>
<p><b>Postconditions:</b> <code>use_count() == 0</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class Y&gt; weak_ptr(shared_ptr&lt;Y&gt; const &amp; r);
weak_ptr(weak_ptr const &amp; r);
template&lt;class Y&gt; weak_ptr(weak_ptr&lt;Y&gt; const &amp; r);</pre>
<blockquote>
<p><b>Effects:</b> If <STRONG>r</STRONG> is <EM>empty</EM>, constructs an <EM>empty</EM>
<STRONG>weak_ptr</STRONG>; otherwise, constructs a <b>weak_ptr</b> that <EM>shares
ownership</EM> with <STRONG>r</STRONG> as if by storing a copy of the
pointer stored in <b>r</b>.</p>
<p><b>Postconditions:</b> <code>use_count() == r.use_count()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h3><a name="destructor">destructor</a></h3>
<pre>~weak_ptr();</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Destroys this <b>weak_ptr</b> but has no effect on the object
its stored pointer points to.</P>
<P><B>Throws:</B> nothing.</P>
</BLOCKQUOTE>
<h3><a name="assignment">assignment</a></h3>
<pre>weak_ptr &amp; operator=(weak_ptr const &amp; r);
template&lt;class Y&gt; weak_ptr &amp; operator=(weak_ptr&lt;Y&gt; const &amp; r);
template&lt;class Y&gt; weak_ptr &amp; operator=(shared_ptr&lt;Y&gt; const &amp; r);</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>weak_ptr(r).swap(*this)</code>.</P>
<P><B>Throws:</B> nothing.</P>
<P><B>Notes:</B> The implementation is free to meet the effects (and the implied
guarantees) via different means, without creating a temporary.</P>
</BLOCKQUOTE>
<h3><a name="use_count">use_count</a></h3>
<pre>long use_count() const;</pre>
<blockquote>
<p><b>Returns:</b> 0 if <STRONG>*this</STRONG> is <EM>empty</EM>; otherwise, the
number of <b>shared_ptr</b> objects that <EM>share ownership</EM> with <STRONG>*this</STRONG>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> <code>use_count()</code> is not necessarily efficient. Use only
for debugging and testing purposes, not for production code.</P>
</blockquote>
<h3><a name="expired">expired</a></h3>
<pre>bool expired() const;</pre>
<blockquote>
<p><b>Returns:</b> <code>use_count() == 0</code>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> <code>expired()</code> may be faster than <code>use_count()</code>.</P>
</blockquote>
<h3><a name="lock">lock</a></h3>
<pre>shared_ptr&lt;T&gt; lock() const;</pre>
<BLOCKQUOTE>
<P><B>Returns:</B> <code>expired()? shared_ptr&lt;T&gt;(): shared_ptr&lt;T&gt;(*this)</code>.</P>
<P><B>Throws:</B> nothing.</P>
</BLOCKQUOTE>
<h3><a name="reset">reset</a></h3>
<pre>void reset();</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>weak_ptr().swap(*this)</code>.</P>
</BLOCKQUOTE>
<h3><a name="swap">swap</a></h3>
<pre>void swap(weak_ptr &amp; b);</pre>
<blockquote>
<p><b>Effects:</b> Exchanges the contents of the two smart pointers.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<h2><a name="functions">Free Functions</a></h2>
<h3><a name="comparison">comparison</a></h3>
<pre>template&lt;class T, class U&gt;
bool operator&lt;(weak_ptr&lt;T&gt; const &amp; a, weak_ptr&lt;U&gt; const &amp; b);</pre>
<blockquote>
<p><b>Returns:</b> an unspecified value such that</p>
<UL>
<LI>
<b>operator&lt;</b> is a strict weak ordering as described in section 25.3 <code>[lib.alg.sorting]</code>
of the C++ standard;
<LI>
under the equivalence relation defined by <STRONG>operator&lt;</STRONG>, <code>!(a
&lt; b) &amp;&amp; !(b &lt; a)</code>, two <STRONG>weak_ptr</STRONG> instances
are equivalent if and only if they <EM>share ownership</EM> or are both <EM>empty</EM>.</LI></UL>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> Allows <STRONG>weak_ptr</STRONG> objects to be used as keys in
associative containers.</P>
</blockquote>
<h3><a name="free-swap">swap</a></h3>
<pre>template&lt;class T&gt;
void swap(weak_ptr&lt;T&gt; &amp; a, weak_ptr&lt;T&gt; &amp; b)</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>a.swap(b)</code>.</P>
<P><B>Throws:</B> nothing.</P>
<P><B>Notes:</B> Matches the interface of <B>std::swap</B>. Provided as an aid to
generic programming.</P>
</BLOCKQUOTE>
<h2><a name="FAQ">Frequently Asked Questions</a></h2>
<P><B>Q.</B> Can an object create a <STRONG>weak_ptr</STRONG> to itself in its
constructor?</P>
<P><b>A.</b> No. A <STRONG>weak_ptr</STRONG> can only be created from a <STRONG>shared_ptr</STRONG>,
and at object construction time no <STRONG>shared_ptr</STRONG> to the object
exists yet. Even if you could create a temporary <STRONG>shared_ptr</STRONG> to <STRONG>
this</STRONG>, it would go out of scope at the end of the constructor, and
all <STRONG>weak_ptr</STRONG> instances would instantly expire.</P>
<P>The solution is to make the constructor private, and supply a factory function
that returns a <STRONG>shared_ptr</STRONG>:<BR>
</P>
<pre>
class X
{
private:
X();
public:
static shared_ptr&lt;X&gt; create()
{
shared_ptr&lt;X&gt; px(new X);
// create weak pointers from px here
return px;
}
};
</pre>
<hr>
<p>$Date$</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body>
</html>