std::unique_ptr::unique_ptr
members of the primary template, unique_ptr<T> |
||
constexpr unique_ptr() noexcept; constexpr unique_ptr( nullptr_t ) noexcept; |
(1) | |
explicit unique_ptr( pointer p ) noexcept; |
(2) | |
unique_ptr( pointer p, /* see below */ d1 ) noexcept; |
(3) | |
unique_ptr( pointer p, /* see below */ d2 ) noexcept; |
(4) | |
unique_ptr( unique_ptr&& u ) noexcept; |
(5) | |
template< class U, class E > unique_ptr( unique_ptr<U, E>&& u ) noexcept; |
(6) | |
template< class U > unique_ptr( std::auto_ptr<U>&& u ) noexcept; |
(7) | (removed in C++17) |
members of the specialization for arrays, unique_ptr<T[]> |
||
constexpr unique_ptr() noexcept; constexpr unique_ptr( nullptr_t ) noexcept; |
(1) | |
explicit unique_ptr( pointer p ) noexcept; |
(2) | (until C++17) |
template<class U> explicit unique_ptr( U p ) noexcept; |
(2) | (since C++17) |
unique_ptr( pointer p, /* see below */ d1 ) noexcept; |
(3) | (until C++17) |
template<class U> unique_ptr( U p, /* see below */ d1 ) noexcept; |
(3) | (since C++17) |
unique_ptr( pointer p, /* see below */ d2 ) noexcept; |
(4) | (until C++17) |
template<class U> unique_ptr( U p, /* see below */ d2 ) noexcept; |
(4) | (since C++17) |
unique_ptr( unique_ptr&& u ) noexcept; |
(5) | |
template< class U, class E > unique_ptr( unique_ptr<U, E>&& u ) noexcept; |
(6) | (since C++17) |
std::unique_ptr
that owns nothing. Value-initializes the stored pointer and the stored deleter. Requires that Deleter
is DefaultConstructible and that construction does not throw an exception.
This constructor is ill-formed if |
(until C++17) |
These overloads only participate in overload resolution if std::is_default_constructible<Deleter>::value is true and Deleter is not a pointer type. |
(since C++17) |
std::unique_ptr
which owns p, initializing the stored pointer with p and value-initializing the stored deleter. Requires that Deleter
is DefaultConstructible and that construction does not throw an exception.
This constructor is ill-formed if |
(until C++17) |
This overload only participates in overload resolution if std::is_default_constructible<Deleter>::value is true and Deleter is not a pointer type. The program is ill-formed if this constructor is selected by class template argument deduction. |
(since C++17) |
std::unique_ptr
object which owns p
, initializing the stored pointer with p
and initializing a deleter D
as below (depends upon whether D
is a reference type)D
is non-reference type A, then the signatures are:
unique_ptr(pointer p, const A& d) noexcept; |
(1) | (requires that Deleter is nothrow-CopyConstructible) |
unique_ptr(pointer p, A&& d) noexcept; |
(2) | (requires that Deleter is nothrow-MoveConstructible) |
D
is an lvalue-reference type A&, then the signatures are:
unique_ptr(pointer p, A& d) noexcept; |
(1) | |
unique_ptr(pointer p, A&& d); |
(2) | |
D
is an lvalue-reference type const A&, then the signatures are:
unique_ptr(pointer p, const A& d) noexcept; |
(1) | |
unique_ptr(pointer p, const A&& d); |
(2) | |
If |
(until C++17) |
If |
(since C++17) |
2-4) in the specialization for arrays behave the same as the constructors that take a pointer parameter in the primary template except that they additionally do not participate in overload resolution unless one of the following is true:
|
(since C++17) |
unique_ptr
by transferring ownership from u
to *this. If Deleter
is not a reference type, requires that it is nothrow-MoveConstructible (if Deleter
is a reference, get_deleter()
and u.get_deleter()
after move construction reference the same value)unique_ptr
by transferring ownership from u
to *this, where u
is constructed with a specified deleter (E
). It depends upon whether E
is a reference type, as following:
E
is a reference type, this deleter is copy constructed from u
's deleter (requires that this construction does not throw)E
is a non-reference type, this deleter is move constructed from u
's deleter (requires that this construction does not throw)pointer
Deleter
is a reference type and E
is the same type as D
, or Deleter
is not a reference type and E
is implicitly convertible to D
6) in the specialization for arrays behaves the same as in the primary template, except that it will only participate in overload resolution if all of the following is true
|
(since C++17) |
unique_ptr
where the stored pointer is initialized with u.release()
and the stored deleter is value-initialized. This constructor only participates in overload resolution if U*
is implicitly convertible to T*
and Deleter
is the same type as std::default_delete<T>
.Parameters
p | - | a pointer to an object to manage |
d1,d2 | - | a deleter to use to destroy the object |
u | - | another smart pointer to acquire the ownership from |
Notes
Instead of using the overload (2) together with new, it is often a better idea to use std::make_unique<T>.
std::unique_ptr<Derived> is implicitly convertible to std::unique_ptr<Base> through the overload (6) (because both the managed pointer and std::default_delete are implicitly convertible)
Because the default constructor is constexpr
, static unique_ptrs are initialized as part of static non-local initialization, before any dynamic non-local initialization begins. This makes it safe to use a unique_ptr in a constructor of any static object.
There is no class template argument deduction from pointer type because it is impossible to distinguish a pointer obtained from array and non-array forms of |
(since C++17) |
Example
#include <iostream> #include <memory> struct Foo { // object to manage Foo() { std::cout << "Foo ctor\n"; } Foo(const Foo&) { std::cout << "Foo copy ctor\n"; } Foo(Foo&&) { std::cout << "Foo move ctor\n"; } ~Foo() { std::cout << "~Foo dtor\n"; } }; struct D { // deleter D() {}; D(const D&) { std::cout << "D copy ctor\n"; } D(D&) { std::cout << "D non-const copy ctor\n";} D(D&&) { std::cout << "D move ctor \n"; } void operator()(Foo* p) const { std::cout << "D is deleting a Foo\n"; delete p; }; }; int main() { std::cout << "Example constructor(1)...\n"; std::unique_ptr<Foo> up1; // up1 is empty std::unique_ptr<Foo> up1b(nullptr); // up1b is empty std::cout << "Example constructor(2)...\n"; { std::unique_ptr<Foo> up2(new Foo); //up2 now owns a Foo } // Foo deleted std::cout << "Example constructor(3)...\n"; D d; { // deleter type is not a reference std::unique_ptr<Foo, D> up3(new Foo, d); // deleter copied } { // deleter type is a reference std::unique_ptr<Foo, D&> up3b(new Foo, d); // up3b holds a reference to d } std::cout << "Example constructor(4)...\n"; { // deleter is not a reference std::unique_ptr<Foo, D> up4(new Foo, D()); // deleter moved } std::cout << "Example constructor(5)...\n"; { std::unique_ptr<Foo> up5a(new Foo); std::unique_ptr<Foo> up5b(std::move(up5a)); // ownership transfer } std::cout << "Example constructor(6)...\n"; { std::unique_ptr<Foo, D> up6a(new Foo, d); // D is copied std::unique_ptr<Foo, D> up6b(std::move(up6a)); // D is moved std::unique_ptr<Foo, D&> up6c(new Foo, d); // D is a reference std::unique_ptr<Foo, D> up6d(std::move(up6c)); // D is copied } #if (__cplusplus < 201703L) std::cout << "Example constructor(7)...\n"; { std::auto_ptr<Foo> up7a(new Foo); std::unique_ptr<Foo> up7b(std::move(up7a)); // ownership transfer } #endif std::cout << "Example array constructor...\n"; { std::unique_ptr<Foo[]> up(new Foo[3]); } // three Foo objects deleted }
Output:
Example constructor(1)... Example constructor(2)... Foo ctor ~Foo dtor Example constructor(3)... Foo ctor D copy ctor D is deleting a Foo ~Foo dtor Foo ctor D is deleting a Foo ~Foo dtor Example constructor(4)... Foo ctor D move ctor D is deleting a Foo ~Foo dtor Example constructor(5)... Foo ctor ~Foo dtor Example constructor(6)... Foo ctor D copy ctor D move ctor Foo ctor D non-const copy ctor D is deleting a Foo ~Foo dtor D is deleting a Foo ~Foo dtor Example constructor(7)... Foo ctor ~Foo dtor Example array constructor... Foo ctor Foo ctor Foo ctor ~Foo dtor ~Foo dtor ~Foo dtor