Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
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 ob-
       ject 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	 Move-
       Assignable, but of
	  neither CopyConstructible nor	CopyAssignable.

Type requirements
	  -
	  Deleter  must	be FunctionObject or lvalue reference to a FunctionOb-
       ject 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	 life-
       time into functions

	    * acquiring	ownership of uniquely-owned objects with dynamic life-
       time from
	      functions

	    *  as the element type in move-aware containers, such as std::vec-
       tor, 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  re-
       sulting
	  std::unique_ptr<B>  will use operator	delete for B, leading to unde-
       fined behavior
	  unless the destructor	of B is	virtual. Note that std::shared_ptr be-
       haves
	  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 exam-
       ple, managing
	  objects located in shared memory, by supplying a  Deleter  that  de-
       fines typedef
	  boost::offset_ptr pointer; or	another	fancy pointer.

	  Feature-test macro: __cpp_lib_constexpr_memory

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<<		      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 <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  de-
       structor
		//  would  have	 invoked  its `next`'s destructor recursively,
       which would
		// cause stack overflow	for sufficiently large lists.
		while (head)
		    head = std::move(head->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,	   de-
       cltype(&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	excep-
       tion 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 instead 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;
		for (int beer =	0; beer	!= 1'000'000; ++beer)
		    wall.push(beer);

		std::cout << "1'000'000	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)

http://cppreference.com		  2022.07.31		    std::unique_ptr(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=std::unique_ptr&sektion=3&manpath=FreeBSD+Ports+15.0>

home | help