std::weak_ptr
is a smart pointer in C++ that provides a non-owning ("weak") reference to an object that is managed by a std::shared_ptr
. Unlike std::shared_ptr
, std::weak_ptr
does not contribute to the reference count of the object. This is particularly useful for breaking circular references, which can occur when two or more std::shared_ptr instances reference each other, preventing the objects from being destroyed even when they are no longer needed.
std::weak_ptr
does not own the object it points to and does not affect its reference count.std::shared_ptr-managed
objects.std::shared_ptr
, a std::weak_ptr
must first be converted to a std::shared_ptr
using the lock()
method. This returns a std::shared_ptr
if the object still exists, or nullptr
if the object has already been destroyed.#include <iostream>
#include <memory>
class MyClass {
public:
MyClass() { std::cout << "MyClass Constructor" << std::endl; }
~MyClass() { std::cout << "MyClass Destructor" << std::endl; }
void sayHello() const { std::cout << "Hello from MyClass" << std::endl; }
};
int main() {
std::shared_ptr<MyClass> sharedPtr = std::make_shared<MyClass>();
std::weak_ptr<MyClass> weakPtr = sharedPtr; // Create a weak_ptr from shared_ptr
if (std::shared_ptr<MyClass> lockedPtr = weakPtr.lock()) {
// Successfully locked the weak_ptr, object is still alive
lockedPtr->sayHello();
} else {
std::cout << "Object has been destroyed" << std::endl;
}
sharedPtr.reset(); // Manually release the shared ownership
if (std::shared_ptr<MyClass> lockedPtr = weakPtr.lock()) {
std::cout << "Object is still alive" << std::endl;
} else {
std::cout << "Object has been destroyed" << std::endl;
}
return 0;
}
std::weak_ptr<MyClass> weakPtr = sharedPtr;
creates a weak_ptr from the shared_ptr. This weak_ptr
does not increase the reference count of the object.weakPtr.lock()
attempts to obtain a std::shared_ptr
from the weak_ptr
. If the object is still alive, it returns a shared_ptr
that can be used to access the object. If the object has been destroyed, it returns nullptr
.sharedPtr.reset();
, the reference count of the original shared_ptr
goes to zero, and the object is destroyed. Any subsequent calls to weakPtr.lock()
will return nullptr.std::weak_ptr
is to break circular references. A circular reference occurs when two objects reference each other through std::shared_ptr
, which can prevent both objects from being destroyed even when they are no longer needed.#include <iostream>
#include <memory>
class Node;
class Node {
public:
std::shared_ptr<Node> next;
std::weak_ptr<Node> prev; // Use weak_ptr to break the circular reference
Node() { std::cout << "Node Constructor" << std::endl; }
~Node() { std::cout << "Node Destructor" << std::endl; }
};
int main() {
std::shared_ptr<Node> node1 = std::make_shared<Node>();
std::shared_ptr<Node> node2 = std::make_shared<Node>();
node1->next = node2; // node1 points to node2
node2->prev = node1; // node2 weakly points back to node1
// Without weak_ptr, this circular reference would prevent both nodes from being destroyed
return 0;
}
node1->next = node2;
creates a shared_ptr
link from node1 to node2.node2->prev = node1;
creates a weak_ptr
link from node2
back to node1
.prev
were a shared_ptr
, both node1
and node2
would have a reference count of 1, preventing them from being destroyed, even when node1
and node2
go out of scope.weak_ptr
for the prev
pointer breaks the cycle, allowing the nodes to be destroyed when the shared_ptr
instances go out of scope.std::weak_ptr
can also be used in scenarios where you want to monitor the existence of an expensive resource (like a large data structure or a database connection) without prolonging its lifetime unnecessarily.
```python

class LargeResource { public: LargeResource() { std::cout << "LargeResource Acquired" << std::endl; } ~LargeResource() { std::cout << "LargeResource Released" << std::endl; } void useResource() const { std::cout << "Using LargeResource" << std::endl; } };
std::weak_ptr
void monitorResource() {
if (std::shared_ptr
int main() {
{
std::shared_ptr
monitorResource(); // Resource is available
}
// After resPtr goes out of scope, the resource is released
monitorResource(); // Resource is no longer available
return 0;
} ```
globalWeakPtr = resPtr;
creates a weak_ptr
that monitors the LargeResource.monitorResource()
, globalWeakPtr.lock()
attempts to create a shared_ptr to access the resource. If the resource still exists, it is used; otherwise, the function reports that the resource is no longer available.resPtr
goes out of scope, the resource is released, and further calls to monitorResource()
indicate that the resource is no longer available.std::weak_ptr
is a non-owning smart pointer used in conjunction with std::shared_ptr
.std::shared_ptr-managed
objects.lock()
to obtain a shared_ptr from a weak_ptr
, which allows you to safely access the object if it still exists.std::weak_ptr
is an essential tool in modern C++ for managing relationships between objects in a way that avoids memory leaks and ensures proper resource management.