| std::unique_ptr(3) | C++ Standard Libary | std::unique_ptr(3) | 
NAME¶
std::unique_ptr - std::unique_ptr
Synopsis¶
 Defined in header <memory>
  
   template<
  
   class T, (1) (since C++11)
  
   class Deleter = std::default_delete<T>
  
   > class unique_ptr;
  
   template <
  
   class T, (2) (since C++11)
  
   class Deleter
  
   > class unique_ptr<T[], Deleter>;
  
   std::unique_ptr is a smart pointer that owns and manages another object
    through a
  
   pointer and disposes of that object when the unique_ptr goes out of
  scope.
  
   The object is disposed of, using the associated deleter when either of the
    following
  
   happens:
  
   * the managing unique_ptr object is destroyed.
  
   * the managing unique_ptr object is assigned another pointer via operator= or
  
   reset().
  
   The object is disposed of, using a potentially user-supplied deleter by
    calling
  
   get_deleter()(ptr). The default deleter uses the delete operator, which
    destroys the
  
   object and deallocates the memory.
  
   A unique_ptr may alternatively own no object, in which case it is called
    empty.
  
   There are two versions of std::unique_ptr:
  
   1. Manages a single object (e.g. allocated with new).
  
   2. Manages a dynamically-allocated array of objects (e.g. allocated with
    new[]).
  
   The class satisfies the requirements of MoveConstructible and MoveAssignable,
    but of
  
   neither CopyConstructible nor CopyAssignable.
Type requirements¶
 -
  
   Deleter must be FunctionObject or lvalue reference to a FunctionObject or
    lvalue
  
   reference to function, callable with an argument of type unique_ptr<T,
  
   Deleter>::pointer.
Notes¶
 Only non-const unique_ptr can transfer the ownership of the
    managed object to
  
   another unique_ptr. If an object's lifetime is managed by a const
    std::unique_ptr,
  
   it is limited to the scope in which the pointer was created.
  
   std::unique_ptr is commonly used to manage the lifetime of objects,
    including:
  
   * providing exception safety to classes and functions that handle objects
    with
  
   dynamic lifetime, by guaranteeing deletion on both normal exit and exit
    through
  
   exception.
  
   * passing ownership of uniquely-owned objects with dynamic lifetime into
  
   functions.
  
   * acquiring ownership of uniquely-owned objects with dynamic lifetime from
  
   functions.
  
   * as the element type in move-aware containers, such as std::vector, which
    hold
  
   pointers to dynamically-allocated objects (e.g. if polymorphic behavior is
  
   desired).
  
   std::unique_ptr may be constructed for an incomplete type T, such as to
    facilitate
  
   the use as a handle in the pImpl idiom. If the default deleter is used, T
    must be
  
   complete at the point in code where the deleter is invoked, which happens in
    the
  
   destructor, move assignment operator, and reset member function of
    std::unique_ptr.
  
   (Conversely, std::shared_ptr can't be constructed from a raw pointer to
    incomplete
  
   type, but can be destroyed where T is incomplete). Note that if T is a class
  
   template specialization, use of unique_ptr as an operand, e.g. !p requires
    T's
  
   parameters to be complete due to ADL.
  
   If T is a derived class of some base B, then std::unique_ptr<T> is
    implicitly
  
   convertible to std::unique_ptr<B>. The default deleter of the resulting
  
   std::unique_ptr<B> will use operator delete for B, leading to undefined
    behavior
  
   unless the destructor of B is virtual. Note that std::shared_ptr behaves
  
   differently: std::shared_ptr<B> will use the operator delete for the
    type T and the
  
   owned object will be deleted correctly even if the destructor of B is not
    virtual.
  
   Unlike std::shared_ptr, std::unique_ptr may manage an object through any
    custom
  
   handle type that satisfies NullablePointer. This allows, for example,
    managing
  
   objects located in shared memory, by supplying a Deleter that defines typedef
  
   boost::offset_ptr pointer; or another fancy pointer.
  
   Feature-test macro Value Std Feature
  
   __cpp_lib_constexpr_memory 202202L (C++23) constexpr std::unique_ptr
Member types¶
 Member type Definition
  
   pointer std::remove_reference<Deleter>::type::pointer if that type
    exists,
  
   otherwise T*. Must satisfy NullablePointer
  
   element_type T, the type of the object managed by this unique_ptr
  
   deleter_type Deleter, the function object or lvalue reference to function or
    to
  
   function object, to be called from the destructor
Member functions¶
 constructor constructs a new unique_ptr
  
   (public member function)
  
   destructor destructs the managed object if such is present
  
   (public member function)
  
   operator= assigns the unique_ptr
  
   (public member function)
Modifiers¶
 release returns a pointer to the managed object and releases the
    ownership
  
   (public member function)
  
   reset replaces the managed object
  
   (public member function)
  
   swap swaps the managed objects
  
   (public member function)
Observers¶
 get returns a pointer to the managed object
  
   (public member function)
  
   get_deleter returns the deleter that is used for destruction of the managed
    object
  
   (public member function)
  
   operator bool checks if there is an associated managed object
  
   (public member function)
Single-object version, unique_ptr<T>¶
 operator* dereferences pointer to the managed object
  
   operator-> (public member function)
Array version, unique_ptr<T[]>¶
 operator[] provides indexed access to the managed array
  
   (public member function)
Non-member functions¶
 make_unique
  
   make_unique_for_overwrite creates a unique pointer that manages a new object
  
   (C++14) (function template)
  
   (C++20)
  
   operator==
  
   operator!=
  
   operator<
  
   operator<= compares to another unique_ptr or with nullptr
  
   operator> (function template)
  
   operator>=
  
   operator<=>
  
   (removed in C++20)
  
   (C++20)
  
   operator<<(std::unique_ptr) outputs the value of the managed pointer to
    an output
  
   (C++20) stream
  
   (function template)
  
   std::swap(std::unique_ptr) specializes the std::swap algorithm
  
   (C++11) (function template)
Helper classes¶
 std::hash<std::unique_ptr> hash support for std::unique_ptr
  
   (C++11) (class template specialization)
Example¶
// Run this code
  
   #include <cassert>
  
   #include <cstdio>
  
   #include <fstream>
  
   #include <iostream>
  
   #include <locale>
  
   #include <memory>
  
   #include <stdexcept>
  
   // helper class for runtime polymorphism demo below
  
   struct B
  
   {
  
   virtual ~B() = default;
  
   virtual void bar() { std::cout << "B::bar\n"; }
  
   };
  
   struct D : B
  
   {
  
   D() { std::cout << "D::D\n"; }
  
   ~D() { std::cout << "D::~D\n"; }
  
   void bar() override { std::cout << "D::bar\n"; }
  
   };
  
   // a function consuming a unique_ptr can take it by value or by rvalue
    reference
  
   std::unique_ptr<D> pass_through(std::unique_ptr<D> p)
  
   {
  
   p->bar();
  
   return p;
  
   }
  
   // helper function for the custom deleter demo below
  
   void close_file(std::FILE* fp)
  
   {
  
   std::fclose(fp);
  
   }
  
   // unique_ptr-based linked list demo
  
   struct List
  
   {
  
   struct Node
  
   {
  
   int data;
  
   std::unique_ptr<Node> next;
  
   };
  
   std::unique_ptr<Node> head;
  
   ~List()
  
   {
  
   // destroy list nodes sequentially in a loop, the default destructor
  
   // would have invoked its `next`'s destructor recursively, which would
  
   // cause stack overflow for sufficiently large lists.
  
   while (head)
  
   {
  
   auto next = std::move(head->next);
  
   head = std::move(next);
  
   }
  
   }
  
   void push(int data)
  
   {
  
   head = std::unique_ptr<Node>(new Node{data, std::move(head)});
  
   }
  
   };
  
   int main()
  
   {
  
   std::cout << "1) Unique ownership semantics demo\n";
  
   {
  
   // Create a (uniquely owned) resource
  
   std::unique_ptr<D> p = std::make_unique<D>();
  
   // Transfer ownership to `pass_through`,
  
   // which in turn transfers ownership back through the return value
  
   std::unique_ptr<D> q = pass_through(std::move(p));
  
   // p is now in a moved-from 'empty' state, equal to nullptr
  
   assert(!p);
  
   }
  
   std::cout << "\n" "2) Runtime polymorphism demo\n";
  
   {
  
   // Create a derived resource and point to it via base type
  
   std::unique_ptr<B> p = std::make_unique<D>();
  
   // Dynamic dispatch works as expected
  
   p->bar();
  
   }
  
   std::cout << "\n" "3) Custom deleter demo\n";
  
   std::ofstream("demo.txt") << 'x'; // prepare the file to read
  
   {
  
   using unique_file_t = std::unique_ptr<std::FILE,
    decltype(&close_file)>;
  
   unique_file_t fp(std::fopen("demo.txt", "r"),
    &close_file);
  
   if (fp)
  
   std::cout << char(std::fgetc(fp.get())) << '\n';
  
   } // `close_file()` called here (if `fp` is not null)
  
   std::cout << "\n" "4) Custom lambda-expression deleter
    and exception safety demo\n";
  
   try
  
   {
  
   std::unique_ptr<D, void(*)(D*)> p(new D, [](D* ptr)
  
   {
  
   std::cout << "destroying from a custom deleter...\n";
  
   delete ptr;
  
   });
  
   throw std::runtime_error(""); // `p` would leak here if it were a
    plain pointer
  
   }
  
   catch (const std::exception&)
  
   {
  
   std::cout << "Caught exception\n";
  
   }
  
   std::cout << "\n" "5) Array form of unique_ptr
    demo\n";
  
   {
  
   std::unique_ptr<D[]> p(new D[3]);
  
   } // `D::~D()` is called 3 times
  
   std::cout << "\n" "6) Linked list demo\n";
  
   {
  
   List wall;
  
   const int enough{1'000'000};
  
   for (int beer = 0; beer != enough; ++beer)
  
   wall.push(beer);
  
   std::cout.imbue(std::locale("en_US.UTF-8"));
  
   std::cout << enough << " bottles of beer on the
    wall...\n";
  
   } // destroys all the beers
  
   }
Possible output:¶
 1) Unique ownership semantics demo
  
   D::D
  
   D::bar
  
   D::~D
  
   2) Runtime polymorphism demo
  
   D::D
  
   D::bar
  
   D::~D
  
   3) Custom deleter demo
  
   x
  
   4) Custom lambda-expression deleter and exception safety demo
  
   D::D
  
   destroying from a custom deleter...
  
   D::~D
  
   Caught exception
  
   5) Array form of unique_ptr demo
  
   D::D
  
   D::D
  
   D::D
  
   D::~D
  
   D::~D
  
   D::~D
  
   6) Linked list demo
  
   1,000,000 bottles of beer on the wall...
See also¶
 shared_ptr smart pointer with shared object ownership semantics
  
   (C++11) (class template)
  
   weak_ptr weak reference to an object managed by std::shared_ptr
  
   (C++11) (class template)
| 2024.06.10 | http://cppreference.com |