2009-03-11 15:08:14 +00:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
< html >
< head >
< title > make_shared and allocate_shared</ title >
< meta http-equiv = "Content-Type" content = "text/html; charset=iso-8859-1" >
</ head >
< body text = "#000000" bgColor = "#ffffff" >
< h1 >< A href = "../../index.htm" >< IMG height = "86" alt = "boost.png (6897 bytes)" src = "../../boost.png" width = "277" align = "middle"
border = "0" ></ A > make_shared and allocate_shared function templates</ h1 >
< p >< A href = "#Introduction" > Introduction</ A >< br >
< A href = "#Synopsis" > Synopsis</ A >< br >
< A href = "#functions" > Free Functions</ A >< br >
< A href = "#example" > Example</ A >< br >
< h2 >< a name = "Introduction" > Introduction</ a ></ h2 >
< p > Consistent use of < a href = "shared_ptr.htm" >< code > shared_ptr</ code ></ a >
can eliminate the need to use an explicit < code > delete</ code > ,
but alone it provides no support in avoiding explicit < code > new</ code > .
There have been repeated requests from users for a factory function that creates
an object of a given type and returns a < code > shared_ptr</ code > to it.
Besides convenience and style, such a function is also exception safe and
considerably faster because it can use a single allocation for both the object
and its corresponding control block, eliminating a significant portion of
< code > shared_ptr</ code > 's construction overhead.
This eliminates one of the major efficiency complaints about < code > shared_ptr</ code > .
</ p >
< p > The header file < boost/make_shared.hpp> provides a family of overloaded function templates,
< code > make_shared</ code > and < code > allocate_shared</ code > , to address this need.
< code > make_shared</ code > uses the global operator < code > new</ code > to allocate memory,
whereas < code > allocate_shared</ code > uses an user-supplied allocator, allowing finer control.</ p >
< p >
The rationale for choosing the name < code > make_shared</ code > is that the expression
< code > make_shared< Widget> ()</ code > can be read aloud and conveys the intended meaning.</ p >
< h2 >< a name = "Synopsis" > Synopsis</ a ></ h2 >
< pre > namespace boost {
template< typename T> class shared_ptr;
template< typename T>
shared_ptr< T> < a href = "#functions" > make_shared</ a > ();
template< typename T, typename A>
shared_ptr< T> < a href = "#functions" > allocate_shared</ a > ( A const & );
2012-12-15 20:20:20 +00:00
#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // C++0x prototypes
2009-03-11 15:08:14 +00:00
template< typename T, typename... Args>
shared_ptr< T> < a href = "#functions" > make_shared</ a > ( Args && ... args );
template< typename T, typename A, typename... Args>
shared_ptr< T> < a href = "#functions" > allocate_shared</ a > ( A const & a, Args && ... args );
#else // no C++0X support
template< typename T, typename Arg1 >
shared_ptr< T> < a href = "#functions" > make_shared</ a > ( Arg1 const & arg1 );
template< typename T, typename Arg1, typename Arg2 >
shared_ptr< T> < a href = "#functions" > make_shared</ a > ( Arg1 const & arg1, Arg2 const & arg2 );
// ...
template< typename T, typename Arg1, typename Arg2, ..., typename ArgN >
shared_ptr< T> < a href = "#functions" > make_shared</ a > ( Arg1 const & arg1, Arg2 const & arg2, ..., ArgN const & argN );
template< typename T, typename A, typename Arg1 >
shared_ptr< T> < a href = "#functions" > allocate_shared</ a > ( A const & a, Arg1 const & arg1 );
template< typename T, typename A, typename Arg1, typename Arg2 >
shared_ptr< T> < a href = "#functions" > allocate_shared</ a > ( Arg1 const & arg1, Arg2 const & arg2 );
// ...
template< typename T, typename A, typename Arg1, typename Arg2, ..., typename ArgN >
shared_ptr< T> < a href = "#functions" > allocate_shared</ a > ( A const & a, Arg1 const & arg1, Arg2 const & arg2, ..., ArgN const & argN );
#endif
}</ pre >
< h2 >< a name = "functions" > Free Functions</ a ></ h2 >
< pre > template< class T, class... Args>
shared_ptr< T> make_shared( Args && ... args );
template< class T, class A, class... Args>
shared_ptr< T> allocate_shared( A const & a, Args && ... args );</ pre >
< blockquote >
< p >< b > Requires:</ b > The expression < code > new( pv ) T( std::forward< Args> (args)... )</ code > ,
where < code > pv</ code > is a < code > void*</ code > pointing to storage suitable
to hold an object of type < code > T</ code > ,
shall be well-formed. < code > A</ code > shall be an < em > Allocator</ em > ,
as described in section 20.1.5 (< stong > Allocator requirements</ strong > ) of the C++ Standard.
The copy constructor and destructor of < code > A</ code > shall not throw.</ p >
< p >< b > Effects:</ b > Allocates memory suitable for an object of type < code > T</ code >
and constructs an object in it via the placement new expression < code > new( pv ) T()</ code >
or < code > new( pv ) T( std::forward< Args> (args)... )</ code > .
< code > allocate_shared</ code > uses a copy of < code > a</ code > to allocate memory.
If an exception is thrown, has no effect.</ p >
< p >< b > Returns:</ b > A < code > shared_ptr</ code > instance that stores and owns the address
of the newly constructed object of type < code > T</ code > .</ p >
< p >< b > Postconditions:</ b > < code > get() != 0 && use_count() == 1</ code > .</ p >
< p >< b > Throws:</ b > < code > bad_alloc</ code > , or an exception thrown from < code > A::allocate</ code >
or the constructor of < code > T</ code > .</ p >
< p >< b > Notes:</ b > This implementation allocates the memory required for the
returned < code > shared_ptr</ code > and an object of type < code > T</ code > in a single
allocation. This provides efficiency equivalent to an intrusive smart pointer.</ p >
< p > The prototypes shown above are used if your compiler supports rvalue references
and variadic templates. They perfectly forward the < code > args</ code > parameters to
the constructors of < code > T</ code > .</ p >
< p > Otherwise, the implementation will fall back on
forwarding the arguments to the constructors of < code > T</ code > as const references.
If you need to pass a non-const reference to a constructor of < code > T</ code > ,
you may do so by wrapping the parameter in a call to < code > boost::ref</ code > .
In addition, you will be
limited to a maximum of 9 arguments (not counting the allocator argument of
allocate_shared).</ p >
</ blockquote >
< h2 >< a name = "example" > Example</ a ></ h2 >
< pre > boost::shared_ptr< std::string> x = boost::make_shared< std::string> ("hello, world!");
std::cout << *x;</ pre >
< hr >
< p >
$Date: 2008-05-19 15:42:39 -0400 (Mon, 19 May 2008) $</ p >
< p >< small > Copyright 2008 Peter Dimov. Copyright 2008 Frank Mori Hess.
Distributed under the Boost Software License,
Version 1.0. See accompanying file < A href = "../../LICENSE_1_0.txt" > LICENSE_1_0.txt</ A >
or copy at < A href = "http://www.boost.org/LICENSE_1_0.txt" > http://www.boost.org/LICENSE_1_0.txt</ A > .</ small ></ p >
</ body >
</ html >