forked from boostorg/smart_ptr
Complete scoped_ptr.adoc
This commit is contained in:
@ -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
|
||||
|
||||
|
@ -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_
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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_
|
||||
|
||||
|
@ -11,5 +11,5 @@ http://www.boost.org/LICENSE_1_0.txt
|
||||
# intrusive_ref_counter
|
||||
:toc:
|
||||
:toc-title:
|
||||
:idprefix:
|
||||
:idprefix: intrusive_ref_counter_
|
||||
|
||||
|
@ -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_
|
||||
|
||||
|
@ -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_
|
||||
|
||||
|
@ -11,5 +11,5 @@ http://www.boost.org/LICENSE_1_0.txt
|
||||
# Generic Pointer Casts
|
||||
:toc:
|
||||
:toc-title:
|
||||
:idprefix:
|
||||
:idprefix: pointer_cast_
|
||||
|
||||
|
@ -11,5 +11,5 @@ http://www.boost.org/LICENSE_1_0.txt
|
||||
# pointer_to_other
|
||||
:toc:
|
||||
:toc-title:
|
||||
:idprefix:
|
||||
:idprefix: pointer_to_other_
|
||||
|
||||
|
@ -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_
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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_
|
||||
|
||||
|
@ -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_
|
||||
|
||||
|
@ -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_
|
||||
|
||||
|
@ -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_
|
||||
|
||||
|
Reference in New Issue
Block a user