std::unique_ptr (3) - Linux Manuals

std::unique_ptr: std::unique_ptr


std::unique_ptr - std::unique_ptr


Defined in header <memory>
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 not the requirements of either CopyConstructible or 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


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.

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

              constructs a new unique_ptr
constructor (public member function)
              destructs the managed object if such is present
destructor (public member function)
              assigns the unique_ptr
operator= (public member function)


              returns a pointer to the managed object and releases the ownership
release (public member function)
              replaces the managed object
reset (public member function)
              swaps the managed objects
swap (public member function)


              returns a pointer to the managed object
get (public member function)
              returns the deleter that is used for destruction of the managed object
get_deleter (public member function)
              checks if there is an associated managed object
operator_bool (public member function)

Single-object version, unique_ptr<T>

              dereferences pointer to the managed object
operator* (public member function)

Array version, unique_ptr<T[]>

              provides indexed access to the managed array
operator[] (public member function)

Non-member functions

make_unique_default_init creates a unique pointer that manages a new object
                           (function template)

operator!= compares to another unique_ptr or with nullptr
operator< (function template)

operator<< outputs the value of the managed pointer to an output stream
                           (function template)

std::swap(std::unique_ptr) specializes the std::swap algorithm
                           (function template)

Helper classes

std::hash<std::unique_ptr> hash support for std::unique_ptr
                           (class template specialization)


// Run this code

  #include <iostream>
  #include <vector>
  #include <memory>
  #include <cstdio>
  #include <fstream>
  #include <cassert>
  #include <functional>

  struct B {
    virtual void bar() { std::cout << "B::bar\n"; }
    virtual ~B() = default;
  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)
      return p;

  void close_file(std::FILE* fp) { std::fclose(fp); }

  int main()
    std::cout << "unique ownership semantics demo\n";
        auto p = std::make_unique<D>(); // p is a unique_ptr that owns a D
        auto q = pass_through(std::move(p));
        assert(!p); // now p owns nothing and holds a null pointer
        q->bar(); // and q owns the D object
    } // ~D called here

    std::cout << "Runtime polymorphism demo\n";
      std::unique_ptr<B> p = std::make_unique<D>(); // p is a unique_ptr that owns a D
                                                    // as a pointer to base
      p->bar(); // virtual dispatch

      std::vector<std::unique_ptr<B>> v; // unique_ptr can be stored in a container
      v.emplace_back(new D);
      for(auto& p: v) p->bar(); // virtual dispatch
    } // ~D called 3 times

    std::cout << "Custom deleter demo\n";
    std::ofstream("demo.txt") << 'x'; // prepare the file to read
        std::unique_ptr<std::FILE, decltype(&close_file)> fp(std::fopen("demo.txt", "r"),
        if(fp) // fopen could have failed; in which case fp holds a null pointer
          std::cout << (char)std::fgetc(fp.get()) << '\n';
    } // fclose() called here, but only if FILE* is not a null pointer
      // (that is, if fopen succeeded)

    std::cout << "Custom lambda-expression deleter demo\n";
      std::unique_ptr<D, std::function<void(D*)>> p(new D, [](D* ptr)
              std::cout << "destroying from a custom deleter...\n";
              delete ptr;
          }); // p owns D
    } // the lambda above is called and D is destroyed

    std::cout << "Array form of unique_ptr demo\n";
        std::unique_ptr<D[]> p{new D[3]};
    } // calls ~D 3 times


  unique ownership semantics demo
  Runtime polymorphism demo
  Custom deleter demo
  Custom lambda-expression deleter demo
  destroying from a custom deleter...
  Array form of unique_ptr demo