---
name: "std::shared_ptr"
section: "3"
platform: "linux"
package: "gcc"
version: "16.2.1+r23+gd564253eb6c8-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/std::shared_ptr"
---

# std::shared\_ptr(3)

A smart pointer with reference-counted copy semantics.

## NAME

std::shared\_ptr\< \_Tp \> - A smart pointer with reference-counted copy semantics.

## SYNOPSIS

\#include \<memory\>

### Public Types

using **element\_type**\
 The type pointed to by the stored pointer, remove\_extent\_t\<\_Tp\>.  using **weak\_type**\

### Public Member Functions

constexpr **shared\_ptr** () noexcept\
 Construct an empty shared\_ptr.  template\<typename \_Yp, typename = \_Constructible\<\_Yp\*\>\> **shared\_ptr** (\_Yp \*\_\_p)\
 Construct a shared\_ptr that owns the pointer *\_\_p*.  template\<typename \_Yp, typename \_Deleter, typename = \_Constructible\<\_Yp\*, \_Deleter\>\> **shared\_ptr** (\_Yp \*\_\_p, \_Deleter \_\_d)\
 Construct a shared\_ptr that owns the pointer *\_\_p* and the deleter *\_\_d*.  template\<typename \_Yp, typename \_Deleter, typename \_Alloc, typename = \_Constructible\<\_Yp\*, \_Deleter, \_Alloc\>\> **shared\_ptr** (\_Yp \*\_\_p, \_Deleter \_\_d, \_Alloc \_\_a)\
 Construct a shared\_ptr that owns the pointer *\_\_p* and the deleter *\_\_d*.  template\<typename \_Yp, typename = \_Constructible\<auto\_ptr\<\_Yp\>\>\> **shared\_ptr** (**auto\_ptr**\< \_Yp \> &&\_\_r)\
 **shared\_ptr** (const shared\_ptr &) noexcept=default\
 Copy constructor.  template\<typename \_Yp, typename = \_Constructible\<const shared\_ptr\<\_Yp\>&\>\> **shared\_ptr** (const shared\_ptr\< \_Yp \> &\_\_r) noexcept\
 If *\_\_r* is empty, constructs an empty shared\_ptr; otherwise construct a shared\_ptr that shares ownership with *\_\_r*.  template\<typename \_Yp\> **shared\_ptr** (const shared\_ptr\< \_Yp \> &\_\_r, **element\_type** \*\_\_p) noexcept\
 Constructs a shared\_ptr instance that stores \_\_p and shares ownership with \_\_r.  template\<typename \_Yp, typename = \_Constructible\<const weak\_ptr\<\_Yp\>&\>\> **shared\_ptr** (const **weak\_ptr**\< \_Yp \> &\_\_r)\
 Constructs a shared\_ptr that shares ownership with *\_\_r* and stores a copy of the pointer stored in *\_\_r*.  template\<typename \_Deleter\> **shared\_ptr** (nullptr\_t \_\_p, \_Deleter \_\_d)\
 Construct a shared\_ptr that owns a null pointer and the deleter *\_\_d*.  template\<typename \_Deleter, typename \_Alloc\> **shared\_ptr** (nullptr\_t \_\_p, \_Deleter \_\_d, \_Alloc \_\_a)\
 Construct a shared\_ptr that owns a null pointer and the deleter *\_\_d*.  constexpr **shared\_ptr** (nullptr\_t) noexcept\
 Construct an empty shared\_ptr.  **shared\_ptr** (shared\_ptr &&\_\_r) noexcept\
 Move-constructs a shared\_ptr instance from *\_\_r*.  template\<typename \_Yp, typename = \_Constructible\<shared\_ptr\<\_Yp\>\>\> **shared\_ptr** (shared\_ptr\< \_Yp \> &&\_\_r) noexcept\
 Move-constructs a shared\_ptr instance from *\_\_r*.  template\<typename \_Yp\> **shared\_ptr** (shared\_ptr\< \_Yp \> &&\_\_r, **element\_type** \*\_\_p) noexcept\
 Constructs a shared\_ptr instance that stores \_\_p and shares ownership with \_\_r.  template\<typename \_Tp1, typename\> **shared\_ptr** (**std::auto\_ptr**\< \_Tp1 \> &&\_\_r)\
 template\<typename \_Yp, typename \_Del, typename = \_Constructible\<unique\_ptr\<\_Yp, \_Del\>\>\> **shared\_ptr** (**unique\_ptr**\< \_Yp, \_Del \> &&\_\_r)\
 **element\_type** \* **get** () const noexcept\
 Return the stored pointer.  **operator bool** () const noexcept\
 Return true if the stored pointer is not null.  **element\_type** & **operator\*** () const noexcept\
 **element\_type** \* **operator-\>** () const noexcept\
 template\<typename \_Yp\> \_Assignable\< **auto\_ptr**\< \_Yp \> \> **operator=** (**auto\_ptr**\< \_Yp \> &&\_\_r)\
 **shared\_ptr** & **operator=** (const **shared\_ptr** &) noexcept=default\
 template\<typename \_Yp\> \_Assignable\< const **shared\_ptr**\< \_Yp \> & \> **operator=** (const **shared\_ptr**\< \_Yp \> &\_\_r) noexcept\
 **shared\_ptr** & **operator=** (**shared\_ptr** &&\_\_r) noexcept\
 template\<class \_Yp\> \_Assignable\< **shared\_ptr**\< \_Yp \> \> **operator=** (**shared\_ptr**\< \_Yp \> &&\_\_r) noexcept\
 template\<typename \_Yp, typename \_Del\> \_Assignable\< **unique\_ptr**\< \_Yp, \_Del \> \> **operator=** (**unique\_ptr**\< \_Yp, \_Del \> &&\_\_r)\
 void **reset** () noexcept\
 template\<typename \_Yp\> \_SafeConv\< \_Yp \> **reset** (\_Yp \*\_\_p)\
 template\<typename \_Yp, typename \_Deleter\> \_SafeConv\< \_Yp \> **reset** (\_Yp \*\_\_p, \_Deleter \_\_d)\
 template\<typename \_Yp, typename \_Deleter, typename \_Alloc\> \_SafeConv\< \_Yp \> **reset** (\_Yp \*\_\_p, \_Deleter \_\_d, \_Alloc \_\_a)\
 void **swap** (\_\_shared\_ptr\< \_Tp, \_Lp \> &\_\_other) noexcept\
 Exchange both the owned pointer and the stored pointer.  bool **unique** () const noexcept\
 Return true if use\_count() == 1.  long **use\_count** () const noexcept\
 If \*this owns a pointer, return the number of owners, otherwise zero.

template\<typename \_Tp1\> bool **owner\_before** (\_\_shared\_ptr\< \_Tp1, \_Lp \> const &\_\_rhs) const noexcept\
 Define an ordering based on ownership.  template\<typename \_Tp1\> bool **owner\_before** (\_\_weak\_ptr\< \_Tp1, \_Lp \> const &\_\_rhs) const noexcept\
 Define an ordering based on ownership.

### Friends

template\<typename \_Yp, typename \_Alloc, typename... \_Args\> **shared\_ptr**\< \_NonArray\< \_Yp \> \> **allocate\_shared** (const \_Alloc &, \_Args &&...)\
 template\<typename \_Yp, typename... \_Args\> **shared\_ptr**\< \_NonArray\< \_Yp \> \> **make\_shared** (\_Args &&...)\
 class **weak\_ptr\< \_Tp \>**\

### Related Symbols

(Note that these are not member symbols.)  template\<typename \_Del, typename \_Tp\> \_Del \* **get\_deleter** (const **shared\_ptr**\< \_Tp \> &\_\_p) noexcept\
 20\.7.2.2.10 shared\_ptr get\_deleter  template\<typename \_Ch, typename \_Tr, typename \_Tp, \_Lock\_policy \_Lp\> **std::basic\_ostream**\< \_Ch, \_Tr \> & **operator\<\<** (**std::basic\_ostream**\< \_Ch, \_Tr \> &\_\_os, const \_\_shared\_ptr\< \_Tp, \_Lp \> &\_\_p)\
 Write the stored pointer to an ostream.

template\<typename \_Tp, typename \_Up\> bool **operator==** (const **shared\_ptr**\< \_Tp \> &\_\_a, const **shared\_ptr**\< \_Up \> &\_\_b) noexcept\
 Equality operator for shared\_ptr objects, compares the stored pointers.  template\<typename \_Tp\> bool **operator==** (const **shared\_ptr**\< \_Tp \> &\_\_a, nullptr\_t) noexcept\
 shared\_ptr comparison with nullptr  template\<typename \_Tp\> void **swap** (**shared\_ptr**\< \_Tp \> &\_\_a, **shared\_ptr**\< \_Tp \> &\_\_b) noexcept\
 Swap overload for shared\_ptr.  template\<typename \_Tp, typename \_Up\> **shared\_ptr**\< \_Tp \> **static\_pointer\_cast** (const **shared\_ptr**\< \_Up \> &\_\_r) noexcept\
 Convert type of shared\_ptr, via static\_cast.  template\<typename \_Tp, typename \_Up\> **shared\_ptr**\< \_Tp \> **const\_pointer\_cast** (const **shared\_ptr**\< \_Up \> &\_\_r) noexcept\
 Convert type of shared\_ptr, via const\_cast.  template\<typename \_Tp, typename \_Up\> **shared\_ptr**\< \_Tp \> **dynamic\_pointer\_cast** (const **shared\_ptr**\< \_Up \> &\_\_r) noexcept\
 Convert type of shared\_ptr, via dynamic\_cast.  template\<typename \_Tp, typename \_Up\> **shared\_ptr**\< \_Tp \> **reinterpret\_pointer\_cast** (const **shared\_ptr**\< \_Up \> &\_\_r) noexcept\
 Convert type of shared\_ptr, via reinterpret\_cast.  template\<typename \_Tp, typename \_Up\> **shared\_ptr**\< \_Tp \> **static\_pointer\_cast** (**shared\_ptr**\< \_Up \> &&\_\_r) noexcept\
 Convert type of shared\_ptr rvalue, via static\_cast.  template\<typename \_Tp, typename \_Up\> **shared\_ptr**\< \_Tp \> **const\_pointer\_cast** (**shared\_ptr**\< \_Up \> &&\_\_r) noexcept\
 Convert type of shared\_ptr rvalue, via const\_cast.  template\<typename \_Tp, typename \_Up\> **shared\_ptr**\< \_Tp \> **dynamic\_pointer\_cast** (**shared\_ptr**\< \_Up \> &&\_\_r) noexcept\
 Convert type of shared\_ptr rvalue, via dynamic\_cast.  template\<typename \_Tp, typename \_Up\> **shared\_ptr**\< \_Tp \> **reinterpret\_pointer\_cast** (**shared\_ptr**\< \_Up \> &&\_\_r) noexcept\
 Convert type of shared\_ptr rvalue, via reinterpret\_cast.

template\<typename \_Tp, typename \_Alloc, typename... \_Args\> **shared\_ptr**\< \_NonArray\< \_Tp \> \> **allocate\_shared** (const \_Alloc &\_\_a, \_Args &&... \_\_args)\
 Create an object that is owned by a shared\_ptr.  template\<typename \_Tp, typename... \_Args\> **shared\_ptr**\< \_NonArray\< \_Tp \> \> **make\_shared** (\_Args &&... \_\_args)\
 Create an object that is owned by a shared\_ptr.

## Detailed Description

### template\<typename \_Tp\>

class std::shared\_ptr\< \_Tp \>"A smart pointer with reference-counted copy semantics.

**Since**

C++11

A shared\_ptr object is either empty or *owns* a pointer passed to the constructor. Copies of a shared\_ptr share ownership of the same pointer. When the last shared\_ptr that owns the pointer is destroyed or reset, the owned pointer is freed (either by delete or by invoking a custom deleter that was passed to the constructor).

A shared\_ptr also stores another pointer, which is usually (but not always) the same pointer as it owns. The stored pointer can be retrieved by calling the get() member function.

The equality and relational operators for shared\_ptr only compare the stored pointer returned by get(), not the owned pointer. To test whether two shared\_ptr objects share ownership of the same pointer see std::shared\_ptr::owner\_before and std::owner\_less.

## Member Typedef Documentation

### template\<typename \_Tp\> using std::shared\_ptr\< \_Tp \>::element\_type

The type pointed to by the stored pointer, remove\_extent\_t\<\_Tp\>.

## Constructor & Destructor Documentation

### template\<typename \_Tp\> std::shared\_ptr\< \_Tp \>::shared\_ptr () \[inline\], \[constexpr\], \[noexcept\]

Construct an empty shared\_ptr.

**Postcondition**

use\_count()==0 && get()==0

### template\<typename \_Tp\> std::shared\_ptr\< \_Tp \>::shared\_ptr (const shared\_ptr\< \_Tp \> & ) \[default\], \[noexcept\]

Copy constructor.

### template\<typename \_Tp\> template\<typename \_Yp, typename = \_Constructible\<\_Yp\*\>\> std::shared\_ptr\< \_Tp \>::shared\_ptr (\_Yp \* \_\_p) \[inline\], \[explicit\]

Construct a shared\_ptr that owns the pointer *\_\_p*.

**Parameters**

*\_\_p* A pointer that is convertible to element\_type\*.

**Postcondition**

use\_count() == 1 && get() == \_\_p

**Exceptions**

**std::bad\_alloc***,in* **which case** delete *\_\_p* **is called.**

### template\<typename \_Tp\> template\<typename \_Yp, typename \_Deleter, typename = \_Constructible\<\_Yp\*, \_Deleter\>\> std::shared\_ptr\< \_Tp \>::shared\_ptr (\_Yp \* \_\_p, \_Deleter \_\_d) \[inline\]

**Construct a shared\_ptr that owns the pointer** *\_\_p* **and the deleter** *\_\_d***.**

**Parameters**

*\_\_p* **A pointer.** \
 *\_\_d* **A deleter.**

**Postcondition**

**use\_count() == 1 && get() == \_\_p**

**Exceptions**

**std::bad\_alloc***,in* **which case** *\_\_d(\_\_p)* **is called.**

**Requirements: \_Deleter's copy constructor and destructor must not throw**

**\_\_shared\_ptr will release \_\_p by calling \_\_d(\_\_p)**

### template\<typename \_Tp\> template\<typename \_Deleter\> std::shared\_ptr\< \_Tp \>::shared\_ptr (nullptr\_t \_\_p, \_Deleter \_\_d) \[inline\]

**Construct a shared\_ptr that owns a null pointer and the deleter** *\_\_d***.**

**Parameters**

*\_\_p* **A null pointer constant.** \
 *\_\_d* **A deleter.**

**Postcondition**

**use\_count() == 1 && get() == \_\_p**

**Exceptions**

**std::bad\_alloc***,in* **which case** *\_\_d(\_\_p)* **is called.**

**Requirements: \_Deleter's copy constructor and destructor must not throw**

**The last owner will call \_\_d(\_\_p)**

### template\<typename \_Tp\> template\<typename \_Yp, typename \_Deleter, typename \_Alloc, typename = \_Constructible\<\_Yp\*, \_Deleter, \_Alloc\>\> std::shared\_ptr\< \_Tp \>::shared\_ptr (\_Yp \* \_\_p, \_Deleter \_\_d, \_Alloc \_\_a) \[inline\]

**Construct a shared\_ptr that owns the pointer** *\_\_p* **and the deleter** *\_\_d***.**

**Parameters**

*\_\_p* **A pointer.** \
 *\_\_d* **A deleter.** \
 *\_\_a* **An allocator.**

**Postcondition**

**use\_count() == 1 && get() == \_\_p**

**Exceptions**

**std::bad\_alloc***,in* **which case** *\_\_d(\_\_p)* **is called.**

**Requirements: \_Deleter's copy constructor and destructor must not throw \_Alloc's copy constructor and destructor must not throw.**

**\_\_shared\_ptr will release \_\_p by calling \_\_d(\_\_p)**

### template\<typename \_Tp\> template\<typename \_Deleter, typename \_Alloc\> std::shared\_ptr\< \_Tp \>::shared\_ptr (nullptr\_t \_\_p, \_Deleter \_\_d, \_Alloc \_\_a) \[inline\]

**Construct a shared\_ptr that owns a null pointer and the deleter** *\_\_d***.**

**Parameters**

*\_\_p* **A null pointer constant.** \
 *\_\_d* **A deleter.** \
 *\_\_a* **An allocator.**

**Postcondition**

**use\_count() == 1 && get() == \_\_p**

**Exceptions**

**std::bad\_alloc***,in* **which case** *\_\_d(\_\_p)* **is called.**

**Requirements: \_Deleter's copy constructor and destructor must not throw \_Alloc's copy constructor and destructor must not throw.**

**The last owner will call \_\_d(\_\_p)**

### template\<typename \_Tp\> template\<typename \_Yp\> std::shared\_ptr\< \_Tp \>::shared\_ptr (const shared\_ptr\< \_Yp \> & \_\_r, element\_type \* \_\_p) \[inline\], \[noexcept\]

**Constructs a** shared\_ptr **instance that stores** \_\_p **and shares ownership with** \_\_r**.**

**Parameters**

*\_\_r* **A** shared\_ptr**.** \
 *\_\_p* **A pointer that will remain valid while** \*\_\_r **is valid.**

**Postcondition**

get() == \_\_p && use\_count() == \_\_r.use\_count()

**This can be used to construct a** shared\_ptr **to a sub-object of an object managed by an existing** shared\_ptr**. The complete object will remain valid while any** shared\_ptr **owns it, even if they don't store a pointer to the complete object.**

```
shared_ptr<pair<int,int>> pii(new pair<int,int>());
shared_ptr<int> pi(pii, &pii->first);
assert(pii.use_count() == 2);
```

### template\<typename \_Tp\> template\<typename \_Yp\> std::shared\_ptr\< \_Tp \>::shared\_ptr (shared\_ptr\< \_Yp \> && \_\_r, element\_type \* \_\_p) \[inline\], \[noexcept\]

**Constructs a** shared\_ptr **instance that stores** \_\_p **and shares ownership with** \_\_r**.**

**Parameters**

*\_\_r* **A** shared\_ptr**.** \
 *\_\_p* **A pointer that will remain valid while** \*\_\_r **is valid.**

**Postcondition**

get() == \_\_p && !\_\_r.use\_count() && !\_\_r.get()

**Since**

**C++17**

**This can be used to construct a** shared\_ptr **to a sub-object of an object managed by an existing** shared\_ptr**. The complete object will remain valid while any** shared\_ptr **owns it, even if they don't store a pointer to the complete object.**

```
shared_ptr<pair<int,int>> pii(new pair<int,int>());
shared_ptr<int> pi1(pii, &pii->first);
assert(pii.use_count() == 2);
shared_ptr<int> pi2(std::move(pii), &pii->second);
assert(pii.use_count() == 0);
```

### template\<typename \_Tp\> template\<typename \_Yp, typename = \_Constructible\<const shared\_ptr\<\_Yp\>&\>\> std::shared\_ptr\< \_Tp \>::shared\_ptr (const shared\_ptr\< \_Yp \> & \_\_r) \[inline\], \[noexcept\]

**If** *\_\_r* **is empty, constructs an empty shared\_ptr; otherwise construct a shared\_ptr that shares ownership with** *\_\_r***.**

**Parameters**

*\_\_r* **A shared\_ptr.**

**Postcondition**

**get() == \_\_r.get() && use\_count() == \_\_r.use\_count()**

### template\<typename \_Tp\> std::shared\_ptr\< \_Tp \>::shared\_ptr (shared\_ptr\< \_Tp \> && \_\_r) \[inline\], \[noexcept\]

**Move-constructs a shared\_ptr instance from** *\_\_r***.**

**Parameters**

*\_\_r* **A shared\_ptr rvalue.**

**Postcondition**

**\*this contains the old value of** *\_\_r***,** *\_\_r* **is empty.**

### template\<typename \_Tp\> template\<typename \_Yp, typename = \_Constructible\<shared\_ptr\<\_Yp\>\>\> std::shared\_ptr\< \_Tp \>::shared\_ptr (shared\_ptr\< \_Yp \> && \_\_r) \[inline\], \[noexcept\]

**Move-constructs a shared\_ptr instance from** *\_\_r***.**

**Parameters**

*\_\_r* **A shared\_ptr rvalue.**

**Postcondition**

**\*this contains the old value of** *\_\_r***,** *\_\_r* **is empty.**

### template\<typename \_Tp\> template\<typename \_Yp, typename = \_Constructible\<const weak\_ptr\<\_Yp\>&\>\> std::shared\_ptr\< \_Tp \>::shared\_ptr (const weak\_ptr\< \_Yp \> & \_\_r) \[inline\], \[explicit\]

**Constructs a shared\_ptr that shares ownership with** *\_\_r* **and stores a copy of the pointer stored in** *\_\_r***.**

**Parameters**

*\_\_r* **A weak\_ptr.**

**Postcondition**

**use\_count() == \_\_r.use\_count()**

**Exceptions**

**bad\_weak\_ptr when \_\_r.expired(), in which case the constructor has no effect.**

### template\<typename \_Tp\> std::shared\_ptr\< \_Tp \>::shared\_ptr (nullptr\_t ) \[inline\], \[constexpr\], \[noexcept\]

**Construct an empty shared\_ptr.**

**Postcondition**

**use\_count() == 0 && get() == nullptr**

## Member Function Documentation

### template\<typename \_Tp, \_Lock\_policy \_Lp\> element\_type \* std::\_\_shared\_ptr\< \_Tp, \_Lp \>::get () const \[inline\], \[noexcept\], \[inherited\]

**Return the stored pointer.**

### template\<typename \_Tp, \_Lock\_policy \_Lp\> std::\_\_shared\_ptr\< \_Tp, \_Lp \>::operator bool () const \[inline\], \[explicit\], \[noexcept\], \[inherited\]

**Return true if the stored pointer is not null.**

### template\<typename \_Tp, \_Lock\_policy \_Lp\> template\<typename \_Tp1\> bool std::\_\_shared\_ptr\< \_Tp, \_Lp \>::owner\_before (\_\_shared\_ptr\< \_Tp1, \_Lp \> const & \_\_rhs) const \[inline\], \[noexcept\], \[inherited\]

**Define an ordering based on ownership. This function defines a strict weak ordering between two shared\_ptr or weak\_ptr objects, such that one object is less than the other unless they share ownership of the same pointer, or are both empty.**

### template\<typename \_Tp, \_Lock\_policy \_Lp\> template\<typename \_Tp1\> bool std::\_\_shared\_ptr\< \_Tp, \_Lp \>::owner\_before (\_\_weak\_ptr\< \_Tp1, \_Lp \> const & \_\_rhs) const \[inline\], \[noexcept\], \[inherited\]

**Define an ordering based on ownership. This function defines a strict weak ordering between two shared\_ptr or weak\_ptr objects, such that one object is less than the other unless they share ownership of the same pointer, or are both empty.**

### template\<typename \_Tp, \_Lock\_policy \_Lp\> void std::\_\_shared\_ptr\< \_Tp, \_Lp \>::swap (\_\_shared\_ptr\< \_Tp, \_Lp \> & \_\_other) \[inline\], \[noexcept\], \[inherited\]

**Exchange both the owned pointer and the stored pointer.**

### template\<typename \_Tp, \_Lock\_policy \_Lp\> bool std::\_\_shared\_ptr\< \_Tp, \_Lp \>::unique () const \[inline\], \[noexcept\], \[inherited\]

**Return true if use\_count() == 1.**

### template\<typename \_Tp, \_Lock\_policy \_Lp\> long std::\_\_shared\_ptr\< \_Tp, \_Lp \>::use\_count () const \[inline\], \[noexcept\], \[inherited\]

**If \*this owns a pointer, return the number of owners, otherwise zero.**

## Author

**Generated automatically by Doxygen for libstdc++ from the source code.**
