...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
The shared_array class template stores a pointer to a dynamically allocated array. (Dynamically allocated array are allocated with the C++ new[] expression.) The object pointed to is guaranteed to be deleted when the last shared_array pointing to it is destroyed or reset.
Every shared_array meets the CopyConstructible and Assignable 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 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.
The class template is parameterized on T, the type of the object pointed to. T must meet the smart pointer common requirements.
namespace boost { template<class T> class shared_array { public: typedef T element_type; explicit shared_array(T * p = 0); template<class D> shared_array(T * p, D d); ~shared_array(); // never throws shared_array(shared_array const & r); // never throws shared_array & operator=(shared_array const & r); // never throws void reset(T * p = 0); template<class D> void reset(T * p, D d); T & operator[](std::ptrdiff_t i) const; // never throws T * get() const; // never throws bool unique() const; // never throws long use_count() const; // never throws operator unspecified-bool-type() const; // never throws void swap(shared_array<T> & b); // never throws }; template<class T> bool operator==(shared_array<T> const & a, shared_array<T> const & b); // never throws template<class T> bool operator!=(shared_array<T> const & a, shared_array<T> const & b); // never throws template<class T> bool operator<(shared_array<T> const & a, shared_array<T> const & b); // never throws template<class T> void swap(shared_array<T> & a, shared_array<T> & b); // never throws }
typedef T element_type;
Provides the type of the stored pointer.
explicit shared_array(T * p = 0);
Constructs a shared_array, storing a copy of p, which must be a pointer to an array that was allocated via a C++ new[] expression or be 0. Afterwards, the use count is 1 (even if p == 0; see ~shared_array). The only exception which may be thrown by this constructor is std::bad_alloc. If an exception is thrown, delete[] p is called.
template<class D> shared_array(T * p, D d);
Constructs a shared_array, storing a copy of p and of d. Afterwards, the use count is 1. D's copy constructor and destructor must not throw. When the the time comes to delete the array pointed to by p, the object d is used in the statement d(p). Invoking the object d with parameter p in this way must not throw. The only exception which may be thrown by this constructor is std::bad_alloc. If an exception is thrown, d(p) is called.
shared_array(shared_array const & r); // never throws
Constructs a shared_array, as if by storing a copy of the pointer stored in r. Afterwards, the use count for all copies is 1 more than the initial use count.
~shared_array(); // never throws
Decrements the use count. Then, if the use count is 0, deletes the array pointed to by the stored pointer. Note that delete[] on a pointer with a value of 0 is harmless. T need not be a complete type. 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.
shared_array & operator=(shared_array const & r); // never throws
Constructs a new shared_array as described above, then replaces this shared_array with the new one, destroying the replaced object.
void reset(T * p = 0);
Constructs a new shared_array as described above, then replaces this shared_array with the new one, destroying the replaced object. The only exception which may be thrown is std::bad_alloc. If an exception is thrown, delete[] p is called.
template<class D> void reset(T * p, D d);
Constructs a new shared_array as described above, then replaces this shared_array with the new one, destroying the replaced object. D's copy constructor must not throw. The only exception which may be thrown is std::bad_alloc. If an exception is thrown, d(p) is called.
T & operator[](std::ptrdiff_t i) const; // never throws
Returns a reference to element i of the array pointed to by the stored pointer. Behavior is undefined and almost certainly undesirable if the stored pointer is 0, or if i is less than 0 or is greater than or equal to the number of elements in the array.
T * get() const; // never throws
Returns the stored pointer. T need not be a complete type. See the smart pointer common requirements.
bool unique() const; // never throws
Returns true if no other shared_array is sharing ownership of the stored pointer, false otherwise. T need not be a complete type. See the smart pointer common requirements.
long use_count() const; // never throws
Returns the number of shared_array objects sharing ownership of the stored pointer. T need not be a complete type. See the smart pointer common requirements.
Because use_count is not necessarily efficient to implement for implementations of shared_array that do not use an explicit reference count, it might be removed from some future version. Thus it should be used for debugging purposes only, and not production code.
operator unspecified-bool-type () const; // never throws
Returns an unspecified value that, when used in boolean contexts, is equivalent
to get() != 0
.
void swap(shared_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.
template<class T> bool operator==(shared_array<T> const & a, shared_array<T> const & b); // never throws template<class T> bool operator!=(shared_array<T> const & a, shared_array<T> const & b); // never throws template<class T> bool operator<(shared_array<T> const & a, shared_array<T> const & b); // never throws
Compares the stored pointers of the two smart pointers. T need not be a complete type. See the smart pointer common requirements.
The operator< overload is provided to define an ordering so that shared_array objects can be used in associative containers such as std::map. The implementation uses std::less<T *> to perform the comparison. This ensures that the comparison is handled correctly, since the standard mandates that relational operations on pointers are unspecified (5.9 [expr.rel] paragraph 2) but std::less<> on pointers is well-defined (20.3.3 [lib.comparisons] paragraph 8).
template<class T> void swap(shared_array<T> & a, shared_array<T> & b) // never throws
Equivalent to a.swap(b). Matches the interface of std::swap. Provided as an aid to generic programming.
Revised 09 January 2003
Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version 1.0. See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.