diff --git a/scoped_ptr.htm b/scoped_ptr.htm index ec0057d..a301fa6 100644 --- a/scoped_ptr.htm +++ b/scoped_ptr.htm @@ -1,51 +1,38 @@ - - -
- -The scoped_ptr class template stores a pointer to a dynamically allocated -object. (Dynamically allocated objects are allocated with the C++ 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 example.
- -The scoped_ptr 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 -noncopyable) -signal its intent to retain ownership solely within the current scope. -Because it is noncopyable, it is -safer than shared_ptr or std::auto_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.
- -It cannot be used in C++ Standard Library containers. -See shared_ptr -or std::auto_ptr if scoped_ptr does not meet your needs.
- -It 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. T must meet the smart pointer -common requirements.
- -namespace boost { + +scoped_ptr + + + ++
scoped_ptr + class template
The scoped_ptr class template stores a pointer to a dynamically allocated + object. (Dynamically allocated objects are allocated with the C++ 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 example.
+The scoped_ptr 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 + noncopyable) signal its intent to retain ownership solely within the + current scope. Because it is noncopyable, + it is safer than shared_ptr or std::auto_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 C++ Standard Library + containers. Use shared_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. T must meet the smart pointer + common requirements.
+Synopsis
+namespace boost { template<typename T> class scoped_ptr : noncopyable { @@ -53,7 +40,7 @@ pointed to. T must meet the smart pointer typedef T element_type; explicit scoped_ptr(T * p = 0); // never throws - ~scoped_ptr(); // never throws + ~scoped_ptr(); // never throws void reset(T * p = 0); // never throws @@ -67,75 +54,59 @@ pointed to. T must meet the smart pointer template<typename T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b); // never throws }- -Members
- -element_type
-typedef T element_type;-Provides the type of the stored pointer.
- -constructors
-explicit scoped_ptr(T * p = 0); // never throws-Constructs a scoped_ptr, storing a copy of p, which must -have been allocated via a C++ new expression or be 0. -T is not required be a complete type. -See the smart pointer -common requirements.
- -destructor
-~scoped_ptr(); // never throws-Deletes the object pointed to by the stored pointer. -Note that delete 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 object's destructor does not throw exceptions. -See the smart pointer common requirements.
- -reset
-void reset(T * p = 0); // never throws-If p is not equal to the stored pointer, deletes the object pointed to by the -stored pointer and then stores a copy of p, which must have been allocated via a -C++ new 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 common requirements.
- -indirection
-T & operator*() const; // never throws-Returns a reference to the object pointed to by the stored pointer. -Behavior is undefined if the stored pointer is 0.
-T * operator->() const; // never throws-Returns the stored pointer. Behavior is undefined if the stored pointer is 0.
- -get
-T * get() const; // never throws-Returns the stored pointer. -T need not be a complete type. -See the smart pointer -common requirements.
- -swap
-void swap(scoped_ptr & b); // never throws-Exchanges the contents of the two smart pointers. -T need not be a complete type. -See the smart pointer -common requirements.
- -Free Functions
- -swap
-template<typename T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b); // never throws-Equivalent to a.swap(b). Matches the interface of std::swap. -Provided as an aid to generic programming.
- -Example
- -Here's an example that uses scoped_ptr.
- --+#include <boost/scoped_ptr.hpp> +Members
+element_type
+typedef T element_type;+Provides the type of the stored pointer.
+constructors
+explicit scoped_ptr(T * p = 0); // never throws+Constructs a scoped_ptr, storing a copy of p, which must have been + allocated via a C++ new expression or be 0. T is not required be + a complete type. See the smart pointer common + requirements.
+destructor
+~scoped_ptr(); // never throws+Destroys the object pointed to by the stored pointer, if any, as if by using delete + this->get().
++ 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 common requirements.
+reset
+void reset(T * p = 0); // never throws+If p is not equal to the stored pointer, deletes the object pointed to by the + stored pointer and then stores a copy of p, which must have been allocated via + a C++ new 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 + common requirements.
+indirection
+T & operator*() const; // never throws+Returns a reference to the object pointed to by the stored pointer. Behavior is + undefined if the stored pointer is 0.
+T * operator->() const; // never throws+Returns the stored pointer. Behavior is undefined if the stored pointer is 0.
+get
+T * get() const; // never throws+Returns the stored pointer. T need not be a complete type. See the smart + pointer common requirements.
+swap
+void swap(scoped_ptr & b); // never throws+Exchanges the contents of the two smart pointers. T need not be a + complete type. See the smart pointer common + requirements.
+Free Functions
+swap
+template<typename T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b); // never throws+Equivalent to a.swap(b). Matches the interface of std::swap. + Provided as an aid to generic programming.
+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"; } }; +struct Shoe { ~Shoe() { std::cout << "Buckle my shoe\n"; } }; class MyClass { boost::scoped_ptr<int> ptr; @@ -151,67 +122,55 @@ void main() 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 +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 auto_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 -C++ 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 scoped_ptr_example_test.cpp -sample program includes a header file, 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 scoped_ptr_example.cpp -implementation file.
- -Frequently Asked Questions
- -Q. Why doesn't scoped_ptr have a release() member?
- -
-A. Because the point of scoped_ptr is to signal intent, not -to transfer ownership. Use std::auto_ptr if ownership transfer is -required.
- -Revised 1 February 2002
- -Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. -Permission to copy, use, modify, sell and distribute this document is granted -provided this copyright notice appears in all copies. -This document is provided "as is" without express or implied warranty, -and with no claim as to its suitability for any purpose.
- - - +Rationale
+The primary reason to use scoped_ptr rather than auto_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 C++ 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 scoped_ptr_example_test.cpp sample + program includes a header file, 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 scoped_ptr_example.cpp implementation + file.
+Frequently Asked Questions
+Q. Why doesn't scoped_ptr have a release() member?
+
+ A. 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 out of + its scope, weakening its role as a way of limiting resource lifetime to a given + scope. Use std::auto_ptr where transfer of ownership is + required. (supplied by Dave Abrahams)
+Revised + 17 September 2002
+Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. + Copyright 2002 Peter Dimov. Permission to copy, use, modify, sell and + distribute this document is granted provided this copyright notice appears in + all copies. This document is provided "as is" without express or implied + warranty, and with no claim as to its suitability for any purpose.
+ diff --git a/shared_array.htm b/shared_array.htm index 7b904e9..52c58e6 100644 --- a/shared_array.htm +++ b/shared_array.htm @@ -15,13 +15,13 @@ requirements of the C++ Standard Library, and so can be used in standard library containers. Comparison operators are supplied so that shared_array works with the standard library's associative containers. -Normally, a shared_array cannot correctly hold a pointer to a single - dynamically allocated object. See shared_ptr - for that usage.
-Because the implementation uses reference counting, shared_array will not - work correctly with cyclic data structures. For example, if main() holds - a shared_array to A, which directly or indirectly holds a shared_array - back to A, A's use count will be 2. Destruction of the original shared_array +
Normally, a shared_array cannot correctly hold a pointer to an object + that has been allocated with the non-array form of new. See + shared_ptr for that usage.
+Because the implementation uses reference counting, cycles of shared_array + instances will not be reclaimed. For example, if main() holds a shared_array + to A, which directly or indirectly holds a shared_array back to A, + A's use count will be 2. Destruction of the original shared_array will leave A dangling with a use count of 1.
A shared_ptr to a std::vector is an alternative to a shared_array that is a bit heavier duty but far more flexible.
diff --git a/shared_ptr.htm b/shared_ptr.htm index dce72c4..291005f 100644 --- a/shared_ptr.htm +++ b/shared_ptr.htm @@ -150,9 +150,12 @@ void bad()[It might be convenient to relax the requirements on shared_ptr's signature, allowing an additional, defaulted, template parameter; the parameter can encode the threading model, for example. This would help in detecting - possible ODR violations. On the other hand, using shared_ptr as - an argument to a template template parameter requires an exact signature - match.]
+ possible ODR violations. +On the other hand, using shared_ptr as an argument to + a template template parameter requires an exact signature match. Metaprogramming + experts tend to deemphasize template template parameters as they are too + inflexible, but the alternative is typically an std::allocator::rebind-type + "hack".]
Members
element_type
typedef T element_type;@@ -229,18 +232,18 @@ void bad() pointer users.]template<typename Y, typename D> shared_ptr(Y * p, D d);-Requirements: p must be convertible to T *. The copy - constructor and destructor of D must not throw. The expression
d2(p)
, - where d2 is a copy of d, must be well-formed, - must not invoke undefined behavior, and must not throw exceptions. +Requirements: p must be convertible to T *. D + must be CopyConstructible. The copy constructor and destructor + of D must not throw. The expression
d(p)
must be + well-formed, must not invoke undefined behavior, and must not throw exceptions.Effects: Constructs a shared_ptr, storing a copy of p and d.
Postconditions: use count is 1.
Throws: std::bad_alloc.
Exception safety: If an exception is thrown,
-d(p)
is called.Notes: When the the time comes to delete the object pointed to by p, -
+d2(p)
is invoked, where d2 is the stored copy of - d.Notes: When the the time comes to delete the object pointed to by p, + the stored copy of d is invoked with the stored copy of p + as an argument.
[Custom deallocators allow a factory function returning a shared_ptr to insulate the user from its memory allocation strategy. Since the deallocator @@ -311,9 +314,10 @@ template<typename Y> shared_ptr & operator=(shared_ptr<Y> const template<typename Y> shared_ptr & operator=(std::auto_ptr<Y> & r);
+Effects: Equivalent to
-shared_ptr(r).swap(*this)
.Notes: The implementation is free to meet the effects (and the implied - guarantees) via different means, without creating a temporary. In particular, - in the example:
+Notes: 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:
shared_ptr<int> p(new int); shared_ptr<void> q(p); @@ -322,6 +326,12 @@ q = p;both assignments may be no-ops.
[Some experts consider the note to be redundant, as it appears to essentially + mirror the "as if" rile. However, experience suggests that when C++ code is + used to describe effects, it is often misinterpreted as required + implementation. In addition, it is not entirely clear whether the "as if" rule + actually applies here, so it's better to be explicit about the possible + optimizations.]
void reset();
@@ -649,7 +659,7 @@ int * p = a.release(); implementation or a linked list implementation, or some other specific implementation. This is not the intent.
-Revised +
Revised 23 July 2002
Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. Copyright 2002 Peter Dimov. Permission to copy, use, modify, sell and diff --git a/smart_ptr.htm b/smart_ptr.htm index 1e045f1..9e5357a 100644 --- a/smart_ptr.htm +++ b/smart_ptr.htm @@ -1,207 +1,168 @@ - - -
- -Smart Pointers - - - - -- -
Smart -Pointers
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.
- -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.
- -The smart pointer library provides five smart pointer class templates:
- --- --
-- -scoped_ptr -<boost/scoped_ptr.hpp> -Simple sole ownership of single objects. Noncopyable. -- -scoped_array -<boost/scoped_array.hpp> -Simple sole ownership of arrays. Noncopyable. -- -shared_ptr -<boost/shared_ptr.hpp> -Object ownership shared among multiple pointers -- -shared_array -<boost/shared_array.hpp> -Array ownership shared among multiple pointers. -- -weak_ptr -<boost/weak_ptr.hpp> -Non-owning observers of an object owned by shared_ptr. -These templates are designed to complement the std::auto_ptr template.
- -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.
- -A test program, smart_ptr_test.cpp, is -provided to verify correct operation.
- -A page on compatibility with older versions of -the Boost smart pointer library describes some of the changes since earlier versions -of the smart pointer implementation.
- -A page on smart pointer timings will be of -interest to those curious about performance issues.
- -Common Requirements
- -These smart pointer class templates have a template parameter, T, 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 operator delete -for objects of type T throw exceptions.
- -T may be an incomplete type at the point of smart pointer -declaration. Unless otherwise specified, it is required that T -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 checked_delete -function template.
- -Rationale
- -The requirements on T 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 T 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.
- -Note that scoped_ptr requires that T be a complete type -at destruction time, but shared_ptr does not.
- -Exception Safety
- -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 T meets the -common requirements) is std::bad_alloc, -and that is thrown only by functions which are explicitly documented as possibly -throwing std::bad_alloc.
- -Exception-specifications
- -Exception-specifications are not used; see -exception-specification -rationale.
- -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: -
- -// never throws
.Functions which destroy objects of the pointed to type are prohibited from -throwing exceptions by the common requirements.
- -History and Acknowledgements
- -January 2002. Peter Dimov reworked all four classes, adding features, fixing bugs, -and splitting them into four separate headers, and added weak_ptr. See the -compatibility page for a summary of the changes.
- -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.
- -November 1999. Darin Adler provided operator ==, operator !=, and std::swap -and std::less specializations for shared types.
- -September 1999. Luis Coelho provided shared_ptr::swap and shared_array::swap
- -May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams -made a number of suggestions resulting in numerous improvements.
- -October 1998. In 1994 Greg Colvin proposed to the C++ Standards Committee -classes named auto_ptr and counted_ptr which -were very similar to what we now call scoped_ptr and shared_ptr. -The committee document was 94-168/N0555, Exception Safe Smart Pointers. 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.
- -Beman Dawes proposed reviving the original semantics under the names safe_ptr -and counted_ptr at an October, 1998, 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 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 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.
- -
- -Revised 4 February 2002 + 4 February 2002
- -Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. -Permission to copy, use, -modify, sell and distribute this document is granted provided this copyright -notice appears in all copies. This document is provided "as is" -without express or implied warranty, and with no claim as to its suitability for -any purpose.
- - - +Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. + Permission to copy, use, modify, sell and distribute this document is granted + provided this copyright notice appears in all copies. This document is provided + "as is" without express or implied warranty, and with no claim as to its + suitability for any purpose.
+