std::unique_ptr::unique_ptr
From cppreference.com
< cpp | memory | unique ptr
| constexpr unique_ptr(); constexpr unique_ptr( nullptr_t ); |
(1) | (since C++11) |
| explicit unique_ptr( pointer p ); |
(2) | (since C++11) |
| unique_ptr( pointer p, /* see below */ d1 ); |
(3) | (since C++11) |
| unique_ptr( pointer p, /* see below */ d2 ); |
(4) | (since C++11) |
| unique_ptr( unique_ptr&& u ); |
(5) | (since C++11) |
| template< class U, class E > unique_ptr( unique_ptr<U, E>&& u ); |
(6) | (since C++11) |
| template< class U > unique_ptr( auto_ptr<U>&& u ); |
(7) | (since C++11) |
1) Constructs a
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.2) Constructs a
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.3-4) Constructs a
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)
a) If
D is non-reference type A, then the signatures are:
-
unique_ptr(pointer p, const A& d);(requires thatDeleteris nothrow-CopyConstructible) -
unique_ptr(pointer p, A&& d);(requires thatDeleteris nothrow-MoveConstructible)
b) If
D is an lvalue-reference type A&, then the signatures are:
-
unique_ptr(pointer p, A& d); -
unique_ptr(pointer p, A&& d);
c) If
D is an lvalue-reference type const A&, then the signatures are:
-
unique_ptr(pointer p, const A& d); -
unique_ptr(pointer p, const A&& d);
5) Constructs a
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)6) Constructs a
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:
a) if
E is a reference type, this deleter is copy constructed from u's deleter (requires that this construction does not throw)b) if
E is a non-reference type, this deleter is move constructed from u's deleter (requires that this construction does not throw) This constructor only participates in overload resolution if all of the following is true:
a)
unique_ptr<U, E>::pointer is implicitly convertible to pointerb) U is not an array type
c) Either
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 D7) Constructs a
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>.Contents |
[edit] 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 |
[edit] Exceptions
noexcept specification:
noexcept
[edit] Notes
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)
[edit] Example
Run this code
#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 } std::cout << "Example constructor(7)...\n"; { std::auto_ptr<Foo> up7a(new Foo); std::unique_ptr<Foo> up7b(std::move(up7a)); // ownership transfer } }
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