Complete scoped_ptr.adoc

This commit is contained in:
Peter Dimov
2017-06-12 03:12:03 +03:00
parent 0dfb4dad0f
commit dea4e8129d
16 changed files with 238 additions and 40 deletions

View File

@ -7,10 +7,10 @@ See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
# Boost.SmartPtr: Smart Pointer Library
# Boost.SmartPtr: The Smart Pointer Library
Greg Colvin, Beman Dawes, Peter Dimov, Glen Fernandes
:toc: left
:toclevels: 3
:toclevels: 2
:idprefix:
:listing-caption: Code Example
:table-caption: Illustration
@ -53,6 +53,7 @@ include::smart_ptr/shared_array.adoc[]
:leveloffset: -1
[[copyright]]
[appendix]
## Copyright and License

View File

@ -11,5 +11,5 @@ http://www.boost.org/LICENSE_1_0.txt
# enable_shared_from_this
:toc:
:toc-title:
:idprefix:
:idprefix: enable_shared_from_this_

View File

@ -9,9 +9,10 @@ See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[appendix,#history]
[[history]]
[appendix]
# History and Acknowledgments
:idprefix:
:idprefix: history_
## Summer 1994

View File

@ -11,9 +11,7 @@ http://www.boost.org/LICENSE_1_0.txt
[#introduction]
# Introduction
:toc:
:toc-title:
:idprefix:
:idprefix: intro
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
@ -28,22 +26,22 @@ acquisition is initialization" idiom described in Bjarne Stroustrup's "The C++ P
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.
* `<<scoped_ptr,scoped_ptr>>`, used to contain ownership of a dynamically allocated object to the current scope;
* `<<scoped_array,scoped_array>>`, which provides scoped ownership for a dynamically allocated array;
* `<<shared_ptr,shared_ptr>>`, a versatile tool for managing shared ownership of an object or array;
* `<<weak_ptr,weak_ptr>>`, a non-owning observer to a shared_ptr-managed object that can be promoted temporarily to shared_ptr;
* `<<intrusive_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.
* `<<make_shared,make_shared>>`, a factory function for creating objects that returns a `shared_ptr`;
* `<<make_unique,make_unique>>`, a factory function returning `std::unique_ptr`;
* `<<enable_shared_from_this,enable_shared_from_this>>`, a helper base class that enables the acquisition of a `shared_ptr` pointing to `this`;
* `<<pointer_to_other,pointer_to_other>>`, a helper trait for converting one smart pointer type to another;
* `<<pointer_cast,static_pointer_cast>>` and companions, generic smart pointer casts;
* `<<intrusive_ref_counter,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

@ -8,8 +8,8 @@ http://www.boost.org/LICENSE_1_0.txt
////
[#intrusive_ptr]
# intrusive_ptr
# intrusive_ptr: Managing Objects with Embedded Counts
:toc:
:toc-title:
:idprefix:
:idprefix: intrusive_ptr_

View File

@ -11,5 +11,5 @@ http://www.boost.org/LICENSE_1_0.txt
# intrusive_ref_counter
:toc:
:toc-title:
:idprefix:
:idprefix: intrusive_ref_counter_

View File

@ -8,8 +8,8 @@ http://www.boost.org/LICENSE_1_0.txt
////
[#make_shared]
# make_shared
# make_shared: Creating shared_ptr
:toc:
:toc-title:
:idprefix:
:idprefix: make_shared_

View File

@ -8,8 +8,8 @@ http://www.boost.org/LICENSE_1_0.txt
////
[#make_unique]
# make_unique
# make_unique: Creating unique_ptr
:toc:
:toc-title:
:idprefix:
:idprefix: make_unique_

View File

@ -11,5 +11,5 @@ http://www.boost.org/LICENSE_1_0.txt
# Generic Pointer Casts
:toc:
:toc-title:
:idprefix:
:idprefix: pointer_cast_

View File

@ -11,5 +11,5 @@ http://www.boost.org/LICENSE_1_0.txt
# pointer_to_other
:toc:
:toc-title:
:idprefix:
:idprefix: pointer_to_other_

View File

@ -8,8 +8,8 @@ http://www.boost.org/LICENSE_1_0.txt
////
[#scoped_array]
# scoped_array
# scoped_array: Scoped Array Ownership
:toc:
:toc-title:
:idprefix:
:idprefix: scoped_array_

View File

@ -8,8 +8,204 @@ http://www.boost.org/LICENSE_1_0.txt
////
[#scoped_ptr]
# scoped_ptr
# scoped_ptr: Scoped Object Ownership
:toc:
:toc-title:
:idprefix:
:idprefix: scoped_ptr_
## Description
The `scoped_ptr` class template stores a pointer to a dynamically allocated object.
(Dynamically allocated objects are allocated with the {cpp} `new` expression.) The
object pointed to is guaranteed to be deleted, either on destruction of the `scoped_ptr`,
or via an explicit `reset`. See the <<scoped_ptr_example,example>>.
`scoped_ptr` 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 noncopyable) signal its intent to retain
ownership solely within the current scope. Because it is noncopyable, it is safer than `shared_ptr`
for pointers which should not be copied.
Because `scoped_ptr` 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.
`scoped_ptr` cannot be used in {cpp} Standard Library containers. Use `shared_ptr` or `std::unique_ptr`
if you need a smart pointer that can.
`scoped_ptr` cannot correctly hold a pointer to a dynamically allocated array. See `scoped_array` for that usage.
The class template is parameterized on `T`, the type of the object pointed to. Destroying `T` must not thow exceptions,
and `T` must be complete at the point `scoped_ptr<T>::~scoped_ptr` is instantiated.
## Synopsis
`scoped_ptr` is defined in `<boost/smart_ptr/scoped_ptr.hpp>`.
```
namespace boost
{
template<class T> class scoped_ptr
{
private:
scoped_ptr(scoped_ptr const&);
scoped_ptr& operator=(scoped_ptr const&);
void operator==(scoped_ptr const&) const;
void operator!=(scoped_ptr const&) const;
public:
typedef T element_type;
explicit scoped_ptr(T * p = 0) noexcept;
~scoped_ptr() noexcept;
void reset(T * p = 0) noexcept;
T & operator*() const noexcept;
T * operator->() const noexcept;
T * get() const noexcept;
explicit operator bool() const noexcept;
void swap(scoped_ptr & b) noexcept;
};
template<class T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) noexcept;
} // namespace boost
```
## Members
### element_type
typedef T element_type;
Provides the type of the stored pointer.
### constructor
explicit scoped_ptr(T * p = 0) noexcept;
Constructs a `scoped_ptr`, storing a copy of `p`, which must have been allocated via a
{cpp} `new` expression or be 0. `T` is not required be a complete type.
### destructor
~scoped_ptr() noexcept;
Destroys the object pointed to by the stored pointer, if any, as if by using
`delete this\->get()`. `T` must be a complete type.
### reset
void reset(T * p = 0) noexcept;
Deletes the object pointed to by the stored pointer and then stores a copy of
`p`, which must have been allocated via a {cpp} `new` expression or be 0.
Since the previous object needs to be deleted, `T` must be a complete type.
### indirection
T & operator*() const noexcept;
Returns a reference to the object pointed to by the stored pointer. Behavior is undefined if the stored pointer is 0.
T * operator->() const noexcept;
Returns the stored pointer. Behavior is undefined if the stored pointer is 0.
### get
T * get() const noexcept;
Returns the stored pointer. `T` need not be a complete type.
### conversions
explicit operator bool () const noexcept; // never throws
Returns `get() != 0`.
### swap
void swap(scoped_ptr & b) noexcept;
Exchanges the contents of the two smart pointers. `T` need not be a complete type.
## Free Functions
### swap
template<class T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) noexcept;
Equivalent to `a.swap(b)`.
## Example
Here's an example that uses `scoped_ptr`.
```
#include <boost/scoped_ptr.hpp>
#include <iostream>
struct Shoe { ~Shoe() { std::cout << "Buckle my shoe\n"; } };
class MyClass {
boost::scoped_ptr<int> ptr;
public:
MyClass() : ptr(new int) { *ptr = 0; }
int add_one() { return ++*ptr; }
};
int main()
{
boost::scoped_ptr<Shoe> x(new Shoe);
MyClass my_instance;
std::cout << my_instance.add_one() << '\n';
std::cout << my_instance.add_one() << '\n';
}
```
The example program produces the beginning of a child's nursery rhyme:
```
1
2
Buckle my shoe
```
## Rationale
The primary reason to use `scoped_ptr` rather than `std::auto_ptr` or `std::unique_ptr` 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.
A secondary reason to use `scoped_ptr` is to prevent a later maintenance programmer from adding a function that transfers
ownership by returning the `auto_ptr`, because the maintenance programmer saw `auto_ptr`, and assumed ownership could safely be transferred.
Think of `bool` vs `int`. We all know that under the covers `bool` is usually just an `int`. Indeed, some argued against including bool in the {cpp}
standard because of that. But by coding `bool` rather than `int`, you tell your readers what your intent is. Same with `scoped_ptr`; by using it you are signaling intent.
It has been suggested that `scoped_ptr<T>` is equivalent to `std::auto_ptr<T> const`. Ed Brey pointed out, however, that `reset` will not work on a `std::auto_ptr<T> const`.
## Handle/Body Idiom
One common usage of `scoped_ptr` is to implement a handle/body (also called pimpl) idiom which avoids exposing the body (implementation) in the header file.
The `link:../../example/scoped_ptr_example_test.cpp[scoped_ptr_example_test.cpp]` sample program includes a header file,
`link:../../example/scoped_ptr_example.hpp[scoped_ptr_example.hpp]`, which uses a `scoped_ptr<>` to an incomplete type to hide the
implementation. The instantiation of member functions which require a complete type occurs in the `link:../../example/scoped_ptr_example.cpp[scoped_ptr_example.cpp]`
implementation file.
## Frequently Asked Questions
[qanda]
Why doesn't `scoped_ptr` have a `release()` member?::
When reading source code, it is valuable to be able to draw conclusions about program behavior based on the types being used. If `scoped_ptr` 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 `std::auto_ptr` where
transfer of ownership is required. (supplied by Dave Abrahams)

View File

@ -7,9 +7,10 @@ See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[appendix,#shared_array]
[[shared_array]]
[appendix]
# shared_array (deprecated)
:toc:
:toc-title:
:idprefix:
:idprefix: shared_array_

View File

@ -8,8 +8,8 @@ http://www.boost.org/LICENSE_1_0.txt
////
[#shared_ptr]
# shared_ptr
# shared_ptr: Shared Ownership
:toc:
:toc-title:
:idprefix:
:idprefix: shared_ptr_

View File

@ -7,9 +7,10 @@ See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////
[appendix,#techniques]
[[techniques]]
[appendix]
# Smart Pointer Programming Techniques
:toc:
:toc-title:
:idprefix:
:idprefix: techniques_

View File

@ -8,8 +8,8 @@ http://www.boost.org/LICENSE_1_0.txt
////
[#weak_ptr]
# weak_ptr
# weak_ptr: Non-owning Observer
:toc:
:toc-title:
:idprefix:
:idprefix: weak_ptr_