home | help
std::shared...::shared_ptr(3)  C++ Standard Libary std::shared...::shared_ptr(3)

NAME
     std::shared_ptr::shared_ptr - std::shared_ptr::shared_ptr

Synopsis
	constexpr shared_ptr() noexcept;			     (1)
	constexpr shared_ptr( std::nullptr_t ) noexcept;	     (2)
	template< class Y >					     (3)
	explicit shared_ptr( Y* ptr );
	template< class Y, class Deleter >			     (4)
	shared_ptr( Y* ptr, Deleter d );
	template< class Deleter >				     (5)
	shared_ptr( std::nullptr_t ptr, Deleter d );
	template< class Y, class Deleter, class Alloc > 	     (6)
	shared_ptr( Y* ptr, Deleter d, Alloc alloc );
	template< class Deleter, class Alloc >			     (7)
	shared_ptr( std::nullptr_t ptr, Deleter d, Alloc alloc );
	template< class Y >
	shared_ptr( const shared_ptr<Y>& r, element_type* ptr )      (8)
	noexcept;
	template< class Y >					     (8)  (since
     C++20)
	shared_ptr( shared_ptr<Y>&& r, element_type* ptr ) noexcept;
	shared_ptr( const shared_ptr& r ) noexcept;		     (9)
	template< class Y >					     (9)
	shared_ptr( const shared_ptr<Y>& r ) noexcept;
	shared_ptr( shared_ptr&& r ) noexcept;			     (10)
	template< class Y >					     (10)
	shared_ptr( shared_ptr<Y>&& r ) noexcept;
	template< class Y >					     (11)
	explicit shared_ptr( const std::weak_ptr<Y>& r );
	template<  class  Y >					       (12) (re-
     moved in C++17)
	shared_ptr( std::auto_ptr<Y>&& r );
	template< class Y, class Deleter >			     (13)
	shared_ptr( std::unique_ptr<Y, Deleter>&& r );

	Constructs new shared_ptr from a variety of pointer types that refer  to
     an object to
	manage.

	For the purposes of the description below, a pointer type Y* is said
	to  be	compatible with a pointer type T* if either Y* is convertible to
     (since C++17)
	T* or Y is the array type U[N] and T is U cv [] (where cv is some set
	of cv-qualifiers).

	1,2)  Constructs  a  shared_ptr  with  no  managed  object,  i.e.  empty
     shared_ptr.
	3-7)  Constructs a shared_ptr with ptr as the pointer to the managed ob-
     ject.

	For	(3,4,6),     Y*     must     be     convertible      to      T*.
     (until C++17)
	If T is an array type U[N], (3,4,6) do not participate in overload
	resolution if Y(*)[N] is an invalid type or not convertible to T*. If
	T  is  an  array  type	U[],  (3,4,6)  do  not	participate  in overload
     (since C++17)
	resolution if Y(*)[] is an invalid type or not convertible to T*.
	Otherwise, (3,4,6) do not participate in overload resolution if Y* is
	not convertible to T*.

	Additionally:
	3) Uses the delete-expression delete ptr
	if T is not an array type; delete[] ptr if T is an array type
	(since C++17) as the deleter. Y must be a complete type. The delete  ex-
     pression must
	be well-formed, have well-defined behavior and not throw any exceptions.
	This  constructor  additionally does not participate in overload resolu-
     tion if the
	delete expression is not well-formed.
	(since C++17)
	4,5) Uses the specified deleter d as the deleter. The expression  d(ptr)
     must be well
	formed,  have  well-defined  behavior  and not throw any exceptions. The
     construction of
	d and of the stored deleter copied from it must not throw exceptions.

	Deleter 	    must	      be	      CopyConstructible.
     (until C++17)
	These constructors additionally do not participate in overload
	resolution   if   the  expression  d(ptr)  is  not  well-formed,  or  if
     (since C++17)
	std::is_move_constructible_v<D> is false.

	6,7) Same as (4,5), but additionally uses a copy of alloc for allocation
     of data for
	internal use. Alloc must be an Allocator.
	8) The aliasing constructor: constructs a shared_ptr which shares owner-
     ship
	information with the initial value of r, but holds an unrelated and  un-
     managed
	pointer  ptr.  If  this shared_ptr is the last of the group to go out of
     scope, it will
	call the stored deleter for the object originally managed by r. However,
     calling
	get() on this shared_ptr will always return a copy of ptr. It is the re-
     sponsibility
	of the programmer to make sure that this ptr remains valid  as	long  as
     this
	shared_ptr  exists, such as in the typical use cases where ptr is a mem-
     ber of the
	object managed by r or is an alias (e.g., downcast) of r.get()
	For the second overload taking an rvalue, r  is  empty	and  r.get()  ==
     nullptr after
	the call.
	(since C++20)
	9)  Constructs a shared_ptr which shares ownership of the object managed
     by r. If r
	manages no object, *this manages no object either. The template overload
     doesn't
	participate in overload resolution if Y* is not
	implicitly convertible to
	(until C++17)
	compatible with
	(since C++17) T*.
	10) Move-constructs a shared_ptr from r. After the  construction,  *this
     contains a
	copy  of  the  previous state of r, r is empty and its stored pointer is
     null. The
	template overload doesn't participate in overload resolution  if  Y*  is
     not
	implicitly convertible to
	(until C++17)
	compatible with
	(since C++17) T*.
	11) Constructs a shared_ptr which shares ownership of the object managed
     by r.
	Y* must be implicitly convertible to T*.
	(until C++17)
	This overload participates in overload resolution only if Y* is compati-
     ble with T*.
	(since	C++17)	Note that r.lock() may be used for the same purpose: the
     difference is
	that this constructor throws an exception  if  the  argument  is  empty,
     while
	std::weak_ptr<T>::lock()  constructs  an  empty  std::shared_ptr in that
     case.
	12) Constructs a shared_ptr that stores and  owns  the	object	formerly
     owned by r. Y*
	must be convertible to T*. After construction, r is empty.
	13)  Constructs  a shared_ptr which manages the object currently managed
     by r. The
	deleter associated with r is stored for future deletion of  the  managed
     object. r
	manages no object after the call.

	This overload doesn't participate in overload resolution if
	std::unique_ptr<Y,  Deleter>::pointer  is  not	compatible  with  T*. If
     (since C++17)
	r.get() is a null pointer, this overload is equivalent to the default
	constructor (1).

	If Deleter is a reference type, it  is	equivalent  to	shared_ptr(r.re-
     lease(),
	std::ref(r.get_deleter()).    Otherwise,    it	  is	equivalent    to
     shared_ptr(r.release(),
	std::move(r.get_deleter())).

	When  T  is  not  an  array   type,   the   overloads	(3,4,6)   enable
     shared_from_this with ptr,
	and the overload (13) enables shared_from_this with the pointer returned
     by
	r.release().

Parameters
	ptr   - a pointer to an object to manage
	d     - a deleter to use to destroy the object
	alloc - an allocator to use for allocations of data for internal use
	r      -  another smart pointer to share the ownership to or acquire the
     ownership
		from

Exceptions
	3) std::bad_alloc if required additional memory could not  be  obtained.
     May throw
	implementation-defined	exception  for other errors. If an exception oc-
     curs, this
	calls delete ptr
	if T is not an array type, and calls delete[] ptr otherwise
	(since C++17).
	4-7) std::bad_alloc if required additional memory could not be obtained.
     May throw
	implementation-defined exception for other errors. d(ptr) is  called  if
     an exception
	occurs.
	11) std::bad_weak_ptr if r.expired() == true. The constructor has no ef-
     fect in this
	case.
	12)  std::bad_alloc if required additional memory could not be obtained.
     May throw
	implementation-defined exception for other errors. This constructor  has
     no effect if
	an exception occurs.
	13) If an exception is thrown, the constructor has no effects.

Notes
	A  constructor	enables  shared_from_this  with a pointer ptr of type U*
     means that it
	determines if U has an
	unambiguous and accessible
	(since	C++17)	base  class  that  is  a  specialization   of	std::en-
     able_shared_from_this,
	and if so, the constructor evaluates the statement:

      if (ptr != nullptr && ptr->weak_this.expired())
	  ptr->weak_this = std::shared_ptr<std::remove_cv_t<U>>(
			       *this, const_cast<std::remove_cv_t<U>*>(ptr));

	Where weak_this is the hidden mutable std::weak_ptr member of
	std::enable_shared_from_this.  The assignment to the weak_this member is
     not atomic
	and conflicts with any potentially concurrent access to the same object.
     This
	ensures that future calls to shared_from_this()  would	share  ownership
     with the
	std::shared_ptr created by this raw pointer constructor.

	The  test  ptr->weak_this.expired()  in  the exposition code above makes
     sure that
	weak_this is not reassigned if it already indicates an owner. This  test
     is required
	as of C++17.

	The  raw  pointer  overloads  assume ownership of the pointed-to object.
     Therefore,
	constructing a shared_ptr using the raw pointer overload for  an  object
     that is
	already  managed  by  a  shared_ptr, such as by shared_ptr(ptr.get()) is
     likely to lead
	to undefined behavior, even if the object is of a type derived from
	std::enable_shared_from_this.

	Because the default constructor is  constexpr,	static	shared_ptrs  are
     initialized as
	part  of  static  non-local initialization, before any dynamic non-local
     initialization
	begins. This makes it safe to use a shared_ptr in a constructor  of  any
     static
	object.

	In C++11 and C++14 it is valid to construct a std::shared_ptr<T> from a
	std::unique_ptr<T[]>:

      std::unique_ptr<int[]> arr(new int[1]);
      std::shared_ptr<int> ptr(std::move(arr));

	Since the shared_ptr obtains its deleter (a std::default_delete<T[]> ob-
     ject) from
	the std::unique_ptr, the array will be correctly deallocated.

	This   is   no	 longer   allowed  in  C++17.  Instead	the  array  form
     std::shared_ptr<T[]>
	should be used.

Example
     // Run this code

      #include <iostream>
      #include <memory>

      struct Foo
      {
	  int id{0};
	  Foo(int i = 0) : id{i} { std::cout << "Foo::Foo(" << i <<  ")\n"; }
	  ~Foo() { std::cout << "Foo::~Foo(), id=" << id << '\n'; }
      };

      struct D
      {
	  void operator()(Foo* p) const
	  {
	      std::cout << "Call delete from function object. Foo::id=" << p->id
     << '\n';
	      delete p;
	  }
      };

      int main()
      {
	  {
	      std::cout << "1) constructor with no managed object\n";
	      std::shared_ptr<Foo> sh1;
	  }

	  {
	      std::cout << "2) constructor with object\n";
	      std::shared_ptr<Foo> sh2(new Foo{10});
	      std::cout << "sh2.use_count(): " << sh2.use_count() << '\n';
	      std::shared_ptr<Foo> sh3(sh2);
	      std::cout << "sh2.use_count(): " << sh2.use_count() << '\n';
	      std::cout << "sh3.use_count(): " << sh3.use_count() << '\n';
	  }

	  {
	      std::cout << "3) constructor with object and deleter\n";
	      std::shared_ptr<Foo> sh4(new Foo{11}, D());
	      std::shared_ptr<Foo> sh5(new Foo{12}, [](auto p)
	      {
		  std::cout << "Call delete from lambda... p->id=" <<  p->id  <<
     '\n';
		  delete p;
	      });
	  }
      }

Output:
      1) constructor with no managed object
      2) constructor with object
      Foo::Foo(10)
      sh2.use_count(): 1
      sh2.use_count(): 2
      sh3.use_count(): 2
      Foo::~Foo(), id=10
      3) constructor with object and deleter
      Foo::Foo(11)
      Foo::Foo(12)
      Call delete from lambda... p->id=12
      Foo::~Foo(), id=12
      Call delete from function object. Foo::id=11
      Foo::~Foo(), id=11

	Defect reports

	The  following	behavior-changing  defect  reports were applied retroac-
     tively to
	previously published C++ standards.

	   DR	 Applied to	     Behavior as published		 Correct
     behavior
	LWG  3548  C++11      the constructor from unique_ptr	       move-con-
     structs instead
			    copy-constructed the deleter

See also
	make_shared		      creates a shared pointer	that  manages  a
     new object
	make_shared_for_overwrite     (function template)
	(C++20)
	allocate_shared 	       creates	a  shared pointer that manages a
     new object
	allocate_shared_for_overwrite allocated using an allocator
	(C++20) 		      (function template)
	enable_shared_from_this       allows an object to  create  a  shared_ptr
     referring to
	(C++11) 		      itself
				      (class template)

http://cppreference.com 	   2024.06.10	   std::shared...::shared_ptr(3)

home | help