Smart Pointers: Weak Pointers
What is it?
C++ Smart Pointers std::weak_ptr
is a type of 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 object it points to. 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 other code. std::weak_ptr
is used in conjunction with std::shared_ptr
to break strong reference cycles which could lead to memory leaks.
Syntax
The syntax of declaring and using a std::weak_ptr
is:
std::weak_ptr<T> weakPtr;
Where,
T
is the type of the object to which the weak pointer points.weakPtr
is the name of the weak pointer.
How to use it
To use std::weak_ptr
, follow the below steps:
- Declare and initialize a
std::shared_ptr
. - Create a
std::weak_ptr
from thestd::shared_ptr
. - Use the
lock()
method ofstd::weak_ptr
to get astd::shared_ptr
that shares ownership of the object. If the object has already been deleted, thestd::shared_ptr
will be empty.
Program code snippet example
#include <iostream>
#include <memory>
struct MyClass {
int value;
MyClass(int val) : value(val) { std::cout << "Resource acquired\n"; }
~MyClass() { std::cout << "Resource destroyed\n"; }
};
int main() {
std::weak_ptr<MyClass> weakPtr;
{
std::shared_ptr<MyClass> sharedPtr = std::make_shared<MyClass>(20);
weakPtr = sharedPtr;
auto lockedPtr = weakPtr.lock(); // Get a shared_ptr
if(lockedPtr) {
std::cout << "Weak pointer is valid with value: " << lockedPtr->value << "\n";
}
}
auto lockedPtr = weakPtr.lock(); // Get a shared_ptr
if(!lockedPtr) {
std::cout << "Weak pointer is expired\n";
}
return 0;
}
Output:
Resource acquired
Weak pointer is valid with value: 20
Resource destroyed
Weak pointer is expired
Important to know
std::weak_ptr
does not extend the lifetime of the managed object. The object could be deleted while there are still weak pointers holding a reference to it.- To access the object a
std::weak_ptr
points to, thestd::weak_ptr
must be converted to astd::shared_ptr
using thelock()
method. - The
lock()
method returns astd::shared_ptr
that shares ownership of the managed object if it has not yet been deleted, or an emptystd::shared_ptr
otherwise.
Best practices
When using std::weak_ptr
, it is important to keep the following best practices in mind:
Use
std::weak_ptr
to break cycles: If you havestd::shared_ptr
objects that point to each other, but do not need to keep each other alive, use astd::weak_ptr
for one of the pointers.Always check the result of
lock()
: Before you use the object astd::weak_ptr
points to, always
check the std::shared_ptr
returned from lock()
. The object may have been deleted, and not checking could lead to accessing a deleted object.
- Don't use
std::weak_ptr
to manage resources:std::weak_ptr
is only meant to be a secondary reference to an object that is owned bystd::shared_ptr
s. It does not have the capability to manage a resource, as it does not know when to delete it.
Declare a std::weak_ptr
called boss_ptr2
and assign it with the std::shared_ptr
object of boss_ptr
.