Skip to main content

std::weak_ptr

Defined in header <memory>.

Since C++11
template< class T > class weak_ptr;

std::weak_ptr is a smart pointer that holds a non-owning ("weak") reference to an object that is managed by std::shared_ptr. It must be converted to std::shared_ptr in order to access the referenced object.

std::weak_ptr models temporary ownership: when an object needs to be accessed only if it exists, and it may be deleted at any time by someone else, std::weak_ptr is used to track the object, and it is converted to std::shared_ptr to assume temporary ownership. If the original std::shared_ptr is destroyed at this time, the object's lifetime is extended until the temporary std::shared_ptr is destroyed as well.

Another use for std::weak_ptr is to break reference cycles formed by objects managed by std::shared_ptr. If such cycle is orphaned (i.e., there are no outside shared pointers into the cycle), the shared_ptr reference counts cannot reach zero and the memory is leaked. To prevent this, one of the pointers in the cycle can be made weak.

Member types

pubelement_typeT (until C++17)
std::remove_extent_t<T> (since C++17)

Member functions

pub(constructor)creates a new weak_ptr
(public member function)
pub(destructor)destroys a weak_ptr
(public member function)
puboperator=assigns the weak_ptr
(public member function)

Modifiers

pubresetreleases the ownership of the managed object
(public member function)
pubswapswaps the managed objects
(public member function)

Observers

pubuse_countreturns the number of shared_ptr objects that manage the object
(public member function)
pubexpiredchecks whether the referenced object was already deleted
(public member function)
publockcreates a shared_ptr that manages the referenced object
(public member function)
pubowner_beforeprovides owner-based ordering of weak pointers
(public member function)

Non-member functions

pubstd::swap(std::weak_ptr) (C++11)specializes the std::swap algorithm
(function template)

Helper classes

pubstd::atomic(std::weak_ptr) (C++20)atomic weak pointer
(class template specialization)

Deduction guides (since C++17)

Notes

Like std::shared_ptr, a typical implementation of weak_ptr stores two pointers:

  • a pointer to the control block; and
  • the stored pointer of the std::shared_ptr it was constructed from.

A separate stored pointer is necessary to ensure that converting a std::shared_ptr to weak_ptr and then back works correctly, even for aliased std::shared_ptrs. It is not possible to access the stored pointer in a weak_ptr without locking it into a std::shared_ptr.

Example

Demonstrates how lock is used to ensure validity of the pointer.

#include <iostream>
#include <memory>

std::weak_ptr<int> gw;

void observe()
{
std::cout << "gw.use_count() == " << gw.use_count() << "; ";
// we have to make a copy of shared pointer before usage:
if (std::shared_ptr<int> spt = gw.lock()) {
std::cout << "*spt == " << *spt << '\n';
}
else {
std::cout << "gw is expired\n";
}
}

int main()
{
{
auto sp = std::make_shared<int>(42);
gw = sp;

observe();
}

observe();
}
Result
gw.use_count() == 1; *spt == 42
gw.use_count() == 0; gw is expired

Defect reports

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

DRApplied toBehavior as publishedCorrect behavior
LWG 3001C++17element_type was not updated for array supportupdated

std::weak_ptr

Defined in header <memory>.

Since C++11
template< class T > class weak_ptr;

std::weak_ptr is a smart pointer that holds a non-owning ("weak") reference to an object that is managed by std::shared_ptr. It must be converted to std::shared_ptr in order to access the referenced object.

std::weak_ptr models temporary ownership: when an object needs to be accessed only if it exists, and it may be deleted at any time by someone else, std::weak_ptr is used to track the object, and it is converted to std::shared_ptr to assume temporary ownership. If the original std::shared_ptr is destroyed at this time, the object's lifetime is extended until the temporary std::shared_ptr is destroyed as well.

Another use for std::weak_ptr is to break reference cycles formed by objects managed by std::shared_ptr. If such cycle is orphaned (i.e., there are no outside shared pointers into the cycle), the shared_ptr reference counts cannot reach zero and the memory is leaked. To prevent this, one of the pointers in the cycle can be made weak.

Member types

pubelement_typeT (until C++17)
std::remove_extent_t<T> (since C++17)

Member functions

pub(constructor)creates a new weak_ptr
(public member function)
pub(destructor)destroys a weak_ptr
(public member function)
puboperator=assigns the weak_ptr
(public member function)

Modifiers

pubresetreleases the ownership of the managed object
(public member function)
pubswapswaps the managed objects
(public member function)

Observers

pubuse_countreturns the number of shared_ptr objects that manage the object
(public member function)
pubexpiredchecks whether the referenced object was already deleted
(public member function)
publockcreates a shared_ptr that manages the referenced object
(public member function)
pubowner_beforeprovides owner-based ordering of weak pointers
(public member function)

Non-member functions

pubstd::swap(std::weak_ptr) (C++11)specializes the std::swap algorithm
(function template)

Helper classes

pubstd::atomic(std::weak_ptr) (C++20)atomic weak pointer
(class template specialization)

Deduction guides (since C++17)

Notes

Like std::shared_ptr, a typical implementation of weak_ptr stores two pointers:

  • a pointer to the control block; and
  • the stored pointer of the std::shared_ptr it was constructed from.

A separate stored pointer is necessary to ensure that converting a std::shared_ptr to weak_ptr and then back works correctly, even for aliased std::shared_ptrs. It is not possible to access the stored pointer in a weak_ptr without locking it into a std::shared_ptr.

Example

Demonstrates how lock is used to ensure validity of the pointer.

#include <iostream>
#include <memory>

std::weak_ptr<int> gw;

void observe()
{
std::cout << "gw.use_count() == " << gw.use_count() << "; ";
// we have to make a copy of shared pointer before usage:
if (std::shared_ptr<int> spt = gw.lock()) {
std::cout << "*spt == " << *spt << '\n';
}
else {
std::cout << "gw is expired\n";
}
}

int main()
{
{
auto sp = std::make_shared<int>(42);
gw = sp;

observe();
}

observe();
}
Result
gw.use_count() == 1; *spt == 42
gw.use_count() == 0; gw is expired

Defect reports

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

DRApplied toBehavior as publishedCorrect behavior
LWG 3001C++17element_type was not updated for array supportupdated