...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
boost::movelib::unique_ptr
// In header: <boost/move/unique_ptr.hpp> template<typename T, typename D = default_delete<T> > class unique_ptr { public: // types typedef see_documentation pointer; typedef see_documentation element_type; typedef D deleter_type; // construct/copy/destruct unique_ptr(const unique_ptr &) = delete; unique_ptr() noexcept; unique_ptr(std::nullptr_t) noexcept; template<typename Pointer> explicit unique_ptr(Pointer) noexcept; template<typename Pointer> unique_ptr(Pointer, see_documentation) noexcept; unique_ptr(std::nullptr_t, see_documentation) noexcept; template<typename Pointer> unique_ptr(Pointer, see_documentation) noexcept; unique_ptr(std::nullptr_t, see_documentation) noexcept; unique_ptr(unique_ptr &&) noexcept; template<typename U, typename E> unique_ptr(BOOST_RV_REF_BEG_IF_CXX11 unique_ptr< U, E > BOOST_RV_REF_END_IF_CXX11) noexcept; unique_ptr & operator=(const unique_ptr &) = delete; unique_ptr & operator=(unique_ptr &&) noexcept; template<typename U, typename E> unique_ptr & operator=(unique_ptr< U, E > &&) noexcept; unique_ptr & operator=(std::nullptr_t) noexcept; ~unique_ptr(); // public member functions element_type & operator *() const noexcept; element_type & operator[](std::size_t) const noexcept; pointer operator->() const noexcept; pointer get() const noexcept; D & get_deleter() noexcept; const D & get_deleter() const noexcept; explicit operator bool() const noexcept; pointer release() noexcept; template<typename Pointer> void reset(Pointer) noexcept; void reset() noexcept; void reset(std::nullptr_t) noexcept; void swap(unique_ptr &) noexcept; };
A unique pointer is an object that owns another object and manages that other object through a pointer.
More precisely, a unique pointer is an object u that stores a pointer to a second object p and will dispose of p when u is itself destroyed (e.g., when leaving block scope). In this context, u is said to own p.
The mechanism by which u disposes of p is known as p's associated deleter, a function object whose correct invocation results in p's appropriate disposition (typically its deletion).
Let the notation u.p denote the pointer stored by u, and let u.d denote the associated deleter. Upon request, u can reset (replace) u.p and u.d with another pointer and deleter, but must properly dispose of its owned object via the associated deleter before such replacement is considered completed.
Additionally, u can, upon request, transfer ownership to another unique pointer u2. Upon completion of such a transfer, the following postconditions hold:
u2.p is equal to the pre-transfer u.p,
u.p is equal to nullptr, and
if the pre-transfer u.d maintained state, such state has been transferred to u2.d.
As in the case of a reset, u2 must properly dispose of its pre-transfer owned object via the pre-transfer associated deleter before the ownership transfer is considered complete.
Each object of a type U instantiated from the unique_ptr template specified in this subclause has the strict ownership semantics, specified above, of a unique pointer. In partial satisfaction of these semantics, each such U is MoveConstructible and MoveAssignable, but is not CopyConstructible nor CopyAssignable. The template parameter T of unique_ptr may be an incomplete type.
The uses of unique_ptr include providing exception safety for dynamically allocated memory, passing ownership of dynamically allocated memory to a function, and returning dynamically allocated memory from a function.
If T is an array type (e.g. unique_ptr<MyType[]>) the interface is slightly altered:
Pointers to types derived from T are rejected by the constructors, and by reset.
The observers operator*
and operator->
are not provided.
The indexing observer operator[]
is provided.
typename T
Provides the type of the stored pointer.
typename D = default_delete<T>
The deleter type:
The default type for the template parameter D is default_delete
. A client-supplied template argument D shall be a function object type, lvalue-reference to function, or lvalue-reference to function object type for which, given a value d of type D and a value ptr of type unique_ptr<T, D>::pointer, the expression d(ptr) is valid and has the effect of disposing of the pointer as appropriate for that deleter.
If the deleter's type D is not a reference type, D shall satisfy the requirements of Destructible.
If the type remove_reference<D>::type::pointer
exists, it shall satisfy the requirements of NullablePointer.
unique_ptr
public
typestypedef see_documentation pointer;
If the type remove_reference<D>::type::pointer
exists, then it shall be a synonym for remove_reference<D>::type::pointer
. Otherwise it shall be a synonym for T*.
typedef see_documentation element_type;
If T is an array type, then element_type is equal to T. Otherwise, if T is a type in the form U[], element_type is equal to U.
unique_ptr
public
construct/copy/destructunique_ptr(const unique_ptr &) = delete;
unique_ptr() noexcept;
Requires: D shall satisfy the requirements of DefaultConstructible, and that construction shall not throw an exception.
Effects: Constructs a unique_ptr
object that owns nothing, value-initializing the stored pointer and the stored deleter.
Postconditions: get() == nullptr
. get_deleter()
returns a reference to the stored deleter.
Remarks: If this constructor is instantiated with a pointer type or reference type for the template argument D, the program is ill-formed.
unique_ptr(std::nullptr_t) noexcept;
Effects: Same as unique_ptr()
(default constructor).
template<typename Pointer> explicit unique_ptr(Pointer p) noexcept;
Requires: D shall satisfy the requirements of DefaultConstructible, and that construction shall not throw an exception.
Effects: Constructs a unique_ptr
which owns p, initializing the stored pointer with p and value initializing the stored deleter.
Postconditions: get() == p
. get_deleter()
returns a reference to the stored deleter.
Remarks: If this constructor is instantiated with a pointer type or reference type for the template argument D, the program is ill-formed. This constructor shall not participate in overload resolution unless:
If T is not an array type and Pointer is implicitly convertible to pointer.
If T is an array type and Pointer is a more CV qualified pointer to element_type.
template<typename Pointer> unique_ptr(Pointer p, see_documentation d1) noexcept;
The signature of this constructor depends upon whether D is a reference type.
If D is non-reference type A, then the signature is unique_ptr(pointer p, const A& d)
.
If D is an lvalue-reference type A&, then the signature is unique_ptr(pointer p, A& d)
.
If D is an lvalue-reference type const A&, then the signature is unique_ptr(pointer p, const A& d)
.
Requires: Either
D is not an lvalue-reference type and d is an lvalue or const rvalue. D shall satisfy the requirements of CopyConstructible, and the copy constructor of D shall not throw an exception. This unique_ptr
will hold a copy of d.
D is an lvalue-reference type and d is an lvalue. the type which D references need not be CopyConstructible nor MoveConstructible. This unique_ptr
will hold a D which refers to the lvalue d.
Effects: Constructs a unique_ptr
object which owns p, initializing the stored pointer with p and initializing the deleter as described above.
Postconditions: get() == p
. get_deleter()
returns a reference to the stored deleter. If D is a reference type then get_deleter()
returns a reference to the lvalue d.
Remarks: This constructor shall not participate in overload resolution unless:
If T is not an array type and Pointer is implicitly convertible to pointer.
If T is an array type and Pointer is a more CV qualified pointer to element_type.
unique_ptr(std::nullptr_t, see_documentation d1) noexcept;
Effects: Same effects as template<class Pointer> unique_ptr(Pointer p, deleter_arg_type1 d1)
and additionally get() == nullptr
template<typename Pointer> unique_ptr(Pointer p, see_documentation d2) noexcept;
The signature of this constructor depends upon whether D is a reference type.
If D is non-reference type A, then the signature is unique_ptr(pointer p, A&& d)
.
If D is an lvalue-reference type A&, then the signature is unique_ptr(pointer p, A&& d)
.
If D is an lvalue-reference type const A&, then the signature is unique_ptr(pointer p, const A&& d)
.
Requires: Either
D is not an lvalue-reference type and d is a non-const rvalue. D shall satisfy the requirements of MoveConstructible, and the move constructor of D shall not throw an exception. This unique_ptr
will hold a value move constructed from d.
D is an lvalue-reference type and d is an rvalue, the program is ill-formed.
Effects: Constructs a unique_ptr
object which owns p, initializing the stored pointer with p and initializing the deleter as described above.
Postconditions: get() == p
. get_deleter()
returns a reference to the stored deleter. If D is a reference type then get_deleter()
returns a reference to the lvalue d.
Remarks: This constructor shall not participate in overload resolution unless:
If T is not an array type and Pointer is implicitly convertible to pointer.
If T is an array type and Pointer is a more CV qualified pointer to element_type.
unique_ptr(std::nullptr_t, see_documentation d2) noexcept;
Effects: Same effects as template<class Pointer> unique_ptr(Pointer p, deleter_arg_type2 d2)
and additionally get() == nullptr
unique_ptr(unique_ptr && u) noexcept;
Requires: If D is not a reference type, D shall satisfy the requirements of MoveConstructible. Construction of the deleter from an rvalue of type D shall not throw an exception.
Effects: Constructs a unique_ptr
by transferring ownership from u to *this. If D is a reference type, this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter.
Postconditions: get()
yields the value u.get() yielded before the construction. get_deleter()
returns a reference to the stored deleter that was constructed from u.get_deleter(). If D is a reference type then get_deleter()
and u.get_deleter()
both reference the same lvalue deleter.
template<typename U, typename E> unique_ptr(BOOST_RV_REF_BEG_IF_CXX11 unique_ptr< U, E > BOOST_RV_REF_END_IF_CXX11 u) noexcept;
Requires: If E is not a reference type, construction of the deleter from an rvalue of type E shall be well formed and shall not throw an exception. Otherwise, E is a reference type and construction of the deleter from an lvalue of type E shall be well formed and shall not throw an exception.
Remarks: This constructor shall not participate in overload resolution unless:
unique_ptr<U, E>::pointer
is implicitly convertible to pointer,
U is not an array type, and
either D is a reference type and E is the same type as D, or D is not a reference type and E is implicitly convertible to D.
Effects: Constructs a unique_ptr
by transferring ownership from u to *this. If E is a reference type, this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter.
Postconditions: get()
yields the value u.get()
yielded before the construction. get_deleter()
returns a reference to the stored deleter that was constructed from u.get_deleter()
.
unique_ptr & operator=(const unique_ptr &) = delete;
unique_ptr & operator=(unique_ptr && u) noexcept;
Requires: If D is not a reference type, D shall satisfy the requirements of MoveAssignable and assignment of the deleter from an rvalue of type D shall not throw an exception. Otherwise, D is a reference type; remove_reference<D>::type
shall satisfy the CopyAssignable requirements and assignment of the deleter from an lvalue of type D shall not throw an exception.
Effects: Transfers ownership from u to *this as if by calling reset(u.release())
followed by get_deleter() = std::forward<D>(u.get_deleter())
.
Returns: *this.
template<typename U, typename E> unique_ptr & operator=(unique_ptr< U, E > && u) noexcept;
Requires: If E is not a reference type, assignment of the deleter from an rvalue of type E shall be well-formed and shall not throw an exception. Otherwise, E is a reference type and assignment of the deleter from an lvalue of type E shall be well-formed and shall not throw an exception.
Remarks: This operator shall not participate in overload resolution unless:
unique_ptr<U, E>::pointer
is implicitly convertible to pointer and
U is not an array type.
Effects: Transfers ownership from u to *this as if by calling reset(u.release())
followed by get_deleter() = std::forward<E>(u.get_deleter())
.
Returns: *this.
unique_ptr & operator=(std::nullptr_t) noexcept;
Effects: reset()
.
Postcondition: get() == nullptr
Returns: *this.
~unique_ptr();
Requires: The expression get_deleter()(get())
shall be well formed, shall have well-defined behavior, and shall not throw exceptions.
Effects: If get() == nullpt1r
there are no effects. Otherwise get_deleter()(get())
.
Note: The use of default_delete
requires T to be a complete type
unique_ptr
public member functionselement_type & operator *() const noexcept;
Requires: get() != nullptr
.
Returns: *get()
.
Remarks</b: If T is an array type, the program is ill-formed.
element_type & operator[](std::size_t i) const noexcept;
Requires: i < the number of elements in the array to which the stored pointer points.
Returns: get()[i]
.
Remarks</b: If T is not an array type, the program is ill-formed.
pointer operator->() const noexcept;
Requires: get() != nullptr
.
Returns: get()
.
Note: use typically requires that T be a complete type.
Remarks</b: If T is an array type, the program is ill-formed.
pointer get() const noexcept;
Returns: The stored pointer.
D & get_deleter() noexcept;
Returns: A reference to the stored deleter.
const D & get_deleter() const noexcept;
Returns: A reference to the stored deleter.
explicit operator bool() const noexcept;
Returns: Returns: get() != nullptr.
pointer release() noexcept;
Postcondition: get() == nullptr
.
Returns: The value get()
had at the start of the call to release.
template<typename Pointer> void reset(Pointer p) noexcept;
Requires: The expression get_deleter()(get())
shall be well formed, shall have well-defined behavior, and shall not throw exceptions.
Effects: assigns p to the stored pointer, and then if the old value of the stored pointer, old_p, was not equal to nullptr, calls get_deleter()(old_p)
. Note: The order of these operations is significant because the call to get_deleter()
may destroy *this.
Postconditions: get() == p
. Note: The postcondition does not hold if the call to get_deleter()
destroys *this since this->get()
is no longer a valid expression.
Remarks: This constructor shall not participate in overload resolution unless:
If T is not an array type and Pointer is implicitly convertible to pointer.
If T is an array type and Pointer is a more CV qualified pointer to element_type.
void reset() noexcept;
Requires: The expression get_deleter()(get())
shall be well formed, shall have well-defined behavior, and shall not throw exceptions.
Effects: assigns nullptr to the stored pointer, and then if the old value of the stored pointer, old_p, was not equal to nullptr, calls get_deleter()(old_p)
. Note: The order of these operations is significant because the call to get_deleter()
may destroy *this.
Postconditions: get() == p
. Note: The postcondition does not hold if the call to get_deleter()
destroys *this since this->get()
is no longer a valid expression.
void reset(std::nullptr_t) noexcept;
Effects: Same as reset()
void swap(unique_ptr & u) noexcept;
Requires: get_deleter()
shall be swappable and shall not throw an exception under swap.
Effects: Invokes swap on the stored pointers and on the stored deleters of *this and u.