2002-02-02 18:36:12 +00:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2000-07-27 14:27:00 +00:00
< html >
< head >
2002-02-02 18:36:12 +00:00
< meta http-equiv = "Content-Type" content = "text/html; charset=iso-8859-1" >
2000-07-27 14:27:00 +00:00
< title > scoped_ptr< / title >
< / head >
< body bgcolor = "#FFFFFF" text = "#000000" >
2002-02-02 18:36:12 +00:00
< h1 > < img src = "../../c++boost.gif" alt = "c++boost.gif (8819 bytes)" align = "middle" width = "277" height = "86" > < a name = "scoped_ptr" > scoped_ptr< / a > 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
2001-05-10 16:00:49 +00:00
initialization" facility, without shared-ownership or transfer-of-ownership
2002-02-02 18:36:12 +00:00
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.
2001-05-24 18:42:25 +00:00
Because it is < a href = "../utility/utility.htm#class noncopyable" > noncopyable< / a > , it is
2002-02-02 18:36:12 +00:00
safer than < b > shared_ptr< / b > or < b > std::auto_ptr< / b > for pointers which should not be
2001-05-10 16:00:49 +00:00
copied.< / p >
2002-02-02 18:36:12 +00:00
< p > Because < b > scoped_ptr< / b > is simple, in its usual implementation
2001-05-10 16:00:49 +00:00
every operation is as fast as for a built-in pointer and it has no more space overhead
2002-02-02 18:36:12 +00:00
that a built-in pointer.< / p >
< p > It cannot be used in C++ Standard Library containers.
See < a href = "shared_ptr.htm" > < b > shared_ptr< / b > < / a >
or < b > std::auto_ptr< / b > if < b > scoped_ptr< / b > does not meet your needs.< / p >
< p > It cannot correctly hold a pointer to a
dynamically allocated array. See < a href = "scoped_array.htm" > < b > scoped_array< / b > < / a >
2000-07-27 14:27:00 +00:00
for that usage.< / p >
2002-02-02 18:36:12 +00:00
< 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< typename T> 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 = "#~scoped_ptr" > ~scoped_ptr< / a > (); // never throws
2000-07-27 14:27:00 +00:00
2002-02-02 18:36:12 +00:00
void < a href = "#reset" > reset< / a > (T * p = 0); // never throws
2000-07-27 14:27:00 +00:00
2002-02-02 18:36:12 +00:00
T & < a href = "#indirection" > operator*< / a > () const; // never throws
T * < a href = "#indirection" > operator-> < / a > () const; // never throws
T * < a href = "#get" > get< / a > () const; // never throws
void < a href = "#swap" > swap< / a > (scoped_ptr & b); // never throws
};
2000-07-27 14:27:00 +00:00
2002-02-02 18:36:12 +00:00
template< typename T> void < a href = "#free-swap" > swap< / a > (scoped_ptr< T> & a, scoped_ptr< T> & b); // never throws
2000-07-27 14:27:00 +00:00
}< / pre >
2002-02-02 18:36:12 +00:00
< h2 > Members< / h2 >
< h3 > < a name = "element_type" > element_type< / a > < / h3 >
2000-07-27 14:27:00 +00:00
< pre > typedef T element_type;< / pre >
< p > Provides the type of the stored pointer.< / p >
2002-02-02 18:36:12 +00:00
< 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 = "~scoped_ptr" > destructor< / a > < / h3 >
< pre > ~scoped_ptr(); // never throws< / pre >
< p > Deletes the object 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 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 >
2000-07-27 14:27:00 +00:00
< p > 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
2002-02-02 18:36:12 +00:00
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 & 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-> () 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 = "swap" > swap< / a > < / h3 >
< pre > void swap(scoped_ptr & 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< typename T> void swap(scoped_ptr< T> & a, scoped_ptr< T> & 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 < boost/scoped_ptr.hpp>
#include < iostream>
struct Shoe { ~Shoe() { std::cout < < " Buckle my shoe\n" ; } };
2000-07-27 14:27:00 +00:00
class MyClass {
boost::scoped_ptr< int> ptr;
public:
MyClass() : ptr(new int) { *ptr = 0; }
int add_one() { return ++*ptr; }
2002-02-02 18:36:12 +00:00
};
2000-07-27 14:27:00 +00:00
2002-02-02 18:36:12 +00:00
void main()
{
2000-07-27 14:27:00 +00:00
boost::scoped_ptr< Shoe> x(new Shoe);
MyClass my_instance;
2002-02-02 18:36:12 +00:00
std::cout < < my_instance.add_one() < < '\n';
std::cout < < my_instance.add_one() < < '\n';
}< / pre >
< / blockquote >
< p > The example program produces the beginning of a child's nursery rhyme:< / p >
2000-07-27 14:27:00 +00:00
< blockquote >
< pre > 1
2
Buckle my shoe< / pre >
< / blockquote >
2002-02-02 18:36:12 +00:00
2001-05-24 18:42:25 +00:00
< h2 > Rationale< / h2 >
2002-02-02 18:36:12 +00:00
< 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< T> < / b > is equivalent to
< b > std::auto_ptr< T> const< / b > . Ed Brey pointed out, however, that
< b > reset< / b > will not work on a < b > std::auto_ptr< T> const.< / b > < / p >
2001-05-24 18:42:25 +00:00
< h2 > < a name = "Handle/Body" > Handle/Body< / a > Idiom< / h2 >
2002-02-02 18:36:12 +00:00
2001-05-24 18:42:25 +00:00
< 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
2001-05-22 18:58:21 +00:00
file.< / p >
2002-02-02 18:36:12 +00:00
2001-05-22 18:58:21 +00:00
< p > The < a href = "scoped_ptr_example_test.cpp" > scoped_ptr_example_test.cpp< / a >
sample program includes a header file, < a href = "scoped_ptr_example.hpp" > scoped_ptr_example.hpp< / a > ,
which uses a < b > scoped_ptr< > < / b > to an incomplete type to hide the
2002-02-02 18:36:12 +00:00
implementation. The
instantiation of member functions which require a complete type occurs in
the < a href = "scoped_ptr_example.cpp" > scoped_ptr_example.cpp< / a >
2001-05-24 18:42:25 +00:00
implementation file.< / p >
2002-02-02 18:36:12 +00:00
< h2 > Frequently Asked Questions< / h2 >
2001-05-24 18:42:25 +00:00
< p > < b > Q< / b > . Why doesn't < b > scoped_ptr< / b > have a release() member?< br >
2002-02-02 18:36:12 +00:00
< b > A< / b > . Because the point of < b > scoped_ptr< / b > is to signal intent, not
to transfer ownership. Use < b > std::auto_ptr< / b > if ownership transfer is
2001-05-24 18:42:25 +00:00
required.< / p >
2002-02-02 18:36:12 +00:00
2000-07-27 14:27:00 +00:00
< hr >
2002-02-02 18:36:12 +00:00
< p > Revised <!-- webbot bot="Timestamp" s - type="EDITED" s - format="%d %B %Y" startspan --> 1 February 2002<!-- webbot bot="Timestamp" endspan i - checksum="15110" --> < / p >
< p > 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.< / p >
2000-07-27 14:27:00 +00:00
< / body >
< / html >