diff --git a/include/boost/smart_ptr.hpp b/include/boost/smart_ptr.hpp
index 2111032..3dea3f9 100644
--- a/include/boost/smart_ptr.hpp
+++ b/include/boost/smart_ptr.hpp
@@ -9,6 +9,7 @@
// See http://www.boost.org for most recent version including documentation.
// Revision History
+// 21 May 01 Require complete type on delete (suggested by Vladimir Prus)
// 21 May 01 operator= fails if operand transitively owned by *this, as in a
// linked list (report by Ken Johnson, fix by Beman Dawes)
// 21 Jan 01 Suppress some useless warnings with MSVC (David Abrahams)
@@ -54,8 +55,9 @@
#include
~scoped_array();+
T is required be a complete type at point of instantiation. See Common +Requirements.
Deletes the array pointed to by the stored pointer. Note that in C++ delete[] on a pointer with a value of 0 is harmless.
Does not throw exceptions.
void reset( T* p=0 )();+
T is required be a complete type at point of instantiation. See Common +Requirements.
If p is not equal to the stored pointer, deletes the array 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.
Does not throw exceptions.
T& operator[](std::size_t i) const; // never throws
+T is required be a complete type at point of instantiation. See Common +Requirements.
Returns a reference to element i of the array pointed to by the stored pointer.
Behavior is undefined (and almost certainly undesirable) if get()==0, @@ -79,6 +87,8 @@ or if i is less than 0 or is greater or equal to the number of elements in the array.
T* get() const; // never throws+
T is not required be a complete type at point of instantiation. +See Common Requirements.
Returns the stored pointer.
[To be supplied. In the meantime, see smart_ptr_test.cpp.]
diff --git a/scoped_ptr.htm b/scoped_ptr.htm index 277b38e..4945084 100644 --- a/scoped_ptr.htm +++ b/scoped_ptr.htm @@ -59,25 +59,38 @@ template<typename T> class scoped_ptr : scoped_ptr constructorsexplicit scoped_ptr( T* p=0 ); // never throws+
T is not required be a complete type at point of instantiation. +See Common Requirements.
Constructs a scoped_ptr, storing a copy of p, which must -have been allocated via a C++ new expression or be 0..
+have been allocated via a C++ new expression or be 0.~scoped_ptr();+
T is required be a complete type at point of instantiation. See Common +Requirements.
Deletes the object pointed to by the stored pointer. Note that in C++, delete on a pointer with a value of 0 is harmless.
Does not throw exceptions.
void reset( T* p=0 );+
T is required be a complete type at point of instantiation. See Common +Requirements.
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.
Does not throw exceptions.
T& operator*() const; // never throws+
T is required be a complete type at point of instantiation. See Common +Requirements.
Returns a reference to the object pointed to by the stored pointer.
T* operator->() const; // never throws T* get() const; // never throws+
T is required be a complete type at point of instantiation of +operator->(). See Common +Requirements.
+T is not required be a complete type at point of instantiation of +get(). See Common Requirements.
Both return the stored pointer.
#include <iostream> @@ -106,24 +119,16 @@ output: Buckle my shoe
One common usage of scoped_ptr is to implement a handle/body -structure which avoids exposing the body (implementation) in the header file:
-class handle -{ -public: // simple forwarding functions to the body class - void f(); - void g(int); -private: - friend class body; //incomplete class hides implementation - boost::scoped_ptr<body> imp; -};-
This code requires that class body
have a trivial destructor to
-avoid undefined behavior. This is because the definition of class
-body
is not visible at the time scoped_ptr<> deletes it. See ISO
-5.3.5/5. Note that some compilers will issue a warning even though the
-above code is well defined.
One common usage of scoped_ptr is to implement a handle/body 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.
Revised 21 May 2001
+Revised 22 May 2001
© Copyright Greg Colvin and Beman Dawes 1999. 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"
diff --git a/scoped_ptr_example.cpp b/scoped_ptr_example.cpp
new file mode 100644
index 0000000..3e2e511
--- /dev/null
+++ b/scoped_ptr_example.cpp
@@ -0,0 +1,16 @@
+// Boost scoped_ptr_example implementation file -----------------------------//
+
+#include "scoped_ptr_example.hpp"
+#include
Provides the type of the stored pointer.
explicit shared_array( T* p=0 );+
T is required be a complete type at point of instantiation. See Common +Requirements.
Constructs a shared_array, storing a copy of p, which must have been allocated via a C++ new[] expression or be 0. Afterwards, use_count() is 1 (even if p==0; see ~shared_array).
The only exception which may be thrown is std::bad_alloc. If an exception is thrown, delete[] p is called.
shared_array( const shared_array& r); // never throws+
T is not required be a complete type at point of instantiation. +See Common Requirements.
Constructs a shared_array, as if by storing a copy of the pointer stored in r. Afterwards, use_count() for all copies is 1 more than the initial r.use_count().
~shared_array();+
T is required be a complete type at point of instantiation. See Common +Requirements.
If use_count() == 1, deletes the array pointed to by the stored pointer. Otherwise, use_count() for any remaining copies is decremented by 1. Note that in C++ delete[] on a pointer with @@ -126,6 +132,8 @@ a value of 0 is harmless.
Does not throw exceptions.
shared_array& operator=( const shared_array& r); // never throws+
T is required be a complete type at point of instantiation. See Common +Requirements.
First, if use_count() == 1, deletes the array pointed to by the stored pointer. Otherwise, use_count() for any remaining copies is decremented by 1. Note that in C++ delete[] on a @@ -135,6 +143,8 @@ of the pointer stored in r. Afterwards, use_count()r.use_count().
void reset( T* p=0 );+
T is required be a complete type at point of instantiation. See Common +Requirements.
First, if use_count() == 1, deletes the array pointed to by the stored pointer. Otherwise, use_count() for any remaining copies is decremented by 1. Note that in C++ delete[] @@ -147,6 +157,8 @@ see ~shared_array).
an exception is thrown, delete[] p is called.T& operator[](std::size_t i) const; // never throws
+T is required be a complete type at point of instantiation. See Common +Requirements.
Returns a reference to element i of the array pointed to by the stored pointer.
Behavior is undefined (and almost certainly undesirable) if get()==0, @@ -154,16 +166,24 @@ or if i is less than 0 or is greater or equal to the number of elements in the array.
T* get() const; // never throws+
T is not required be a complete type at point of instantiation. +See Common Requirements.
Returns the stored pointer.
long use_count() const; // never throws
+T is not required be a complete type at point of instantiation. +See Common Requirements.
Returns the number of shared_arrays sharing ownership of the stored pointer.
bool unique() const; // never throws
+T is not required be a complete type at point of instantiation. +See Common Requirements.
Returns use_count() == 1.
void swap( shared_array<T>& other ) throw()
T is not required be a complete type at point of instantiation. +See Common Requirements.
Swaps the two smart pointers, as if by std::swap.
[To be supplied. In the meantime, see smart_ptr_test.cpp.]
diff --git a/shared_ptr.htm b/shared_ptr.htm index 4dd2b87..78ed702 100644 --- a/shared_ptr.htm +++ b/shared_ptr.htm @@ -118,6 +118,8 @@ the macro name BOOST_NO_MEMBER_TEMPLATES is defined.Provides the type of the stored pointer.
explicit shared_ptr( T* p=0 );+
T is required be a complete type at point of instantiation. See Common +Requirements.
Constructs a shared_ptr, storing a copy of p, which must have been allocated via a C++ new expression or be 0. Afterwards, use_count() is 1 (even if p==0; see ~shared_ptr).
@@ -128,6 +130,8 @@ template<typename Y> shared_ptr(const shared_ptr<Y>& r); // never throws template<typename Y> shared_ptr(std::auto_ptr<Y>& r); +T is not required be a complete type at point of instantiation. +See Common Requirements.
Constructs a shared_ptr, as if by storing a copy of the pointer stored in r. Afterwards, use_count() for all copies is 1 more than the initial r.use_count(), or 1 @@ -138,6 +142,8 @@ is std::bad_alloc. If an exception is thrown, that constructor has no effect.
~shared_ptr();+
T is required be a complete type at point of instantiation. See Common +Requirements.
If use_count() == 1, deletes the object pointed to by the stored pointer. Otherwise, use_count() for any remaining copies is decremented by 1. Note that in C++ delete on a pointer @@ -149,6 +155,8 @@ template<typename Y> shared_ptr& operator=(const shared_ptr<Y>& r); template<typename Y> shared_ptr& operator=(std::auto_ptr<Y>& r); +
T is required be a complete type at point of instantiation. See Common +Requirements.
First, if use_count() == 1, deletes the object pointed to by the stored pointer. Otherwise, use_count() for any remaining copies is decremented by 1. Note that in C++ delete on @@ -164,6 +172,8 @@ is std::bad_alloc. If an exception is thrown, the function has no effect.
void reset( T* p=0 );+
T is required be a complete type at point of instantiation. See Common +Requirements.
First, if use_count() == 1, deletes the object pointed to by the stored pointer. Otherwise, use_count() for any remaining copies is decremented by 1.
@@ -176,33 +186,46 @@ on a pointer with a value of 0 is harmless. an exception is thrown, delete p is called.T& operator*() const; // never throws+
T is required be a complete type at point of instantiation. See Common +Requirements.
Returns a reference to the object pointed to by the stored pointer.
T* operator->() const; // never throws T* get() const; // never throws+
T is required be a complete type at point of instantiation of +operator->(). See Common +Requirements.
+T is not required be a complete type at point of instantiation of +get(). See Common Requirements.
Both return the stored pointer.
long use_count() const; // never throws
+T is not required be a complete type at point of instantiation. +See Common Requirements.
Returns the number of shared_ptrs sharing ownership of the stored pointer.
bool unique() const; // never throws
+T is not required be a complete type at point of instantiation. +See Common Requirements.
Returns use_count() == 1.
void swap( shared_ptr<T>& other ) throw()
T is not required be a complete type at point of instantiation. +See Common Requirements.
Swaps the two smart pointers, as if by std::swap.
See shared_ptr_example.cpp for a complete example program.
This program builds a std::vector and std::set of FooPtr's.
Note that after the two containers have been populated, some of the FooPtr objects will have use_count()==1 rather than use_count()==2, since foo_set is a std::set -rather than a std::multiset. Furthermore, use_count() may be even higher +rather than a std::multiset, and thus does not contain duplicate entries. Furthermore, use_count() may be even higher at various times while push_back() and insert() container operations are performed. More complicated yet, the container operations may throw exceptions under a variety of circumstances. Without using a smart pointer, memory and exception management would be a nightmare.
Revised 21 May, 2001 +
Revised 22 May, 2001
© Copyright Greg Colvin and Beman Dawes 1999. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright diff --git a/smart_ptr.htm b/smart_ptr.htm index dc5db1f..b7bcf04 100644 --- a/smart_ptr.htm +++ b/smart_ptr.htm @@ -27,11 +27,11 @@ provides four smart pointer template classes:
A page on Smart Pointer Timings will be of interest to those curious about performance issues.
These smart pointer classes have a template parameter, T, which +
These smart pointer classes have a template parameter, T, which specifies the type of the object pointed to by the smart pointer. The behavior of all four classes is undefined if the destructor or operator delete -for objects of type T throws exceptions.
+for objects of type T throws 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 point of instantiation of all member functions.
The requirements on T are carefully crafted to ensure safety +yet allow handle-body (aka 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.
+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. The +instantiation of member functions which require a complete type occurs in the scoped_ptr_example.cpp +implementation file.
Several functions in these smart pointer classes are specified as having "no effect" or "no effect except such-and-such" if an @@ -78,6 +93,10 @@ never throws.
Functions which destroy objects of the pointed to type are prohibited from throwing exceptions by the Common requirements.
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
@@ -125,7 +144,7 @@ implementation.See the Revision History section of the header for further contributors.
Revised 27 Jul 200022 May 2001
© Copyright Greg Colvin and Beman Dawes 1999. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright