What is weak_ptr in C++: Explanation and Usage
weak_ptr in C++ is a smart pointer that holds a non-owning reference to an object managed by shared_ptr. It allows you to observe the object without affecting its lifetime, preventing circular references that cause memory leaks.How It Works
Imagine you have a shared resource, like a book, that many friends can borrow. shared_ptr is like each friend holding a copy of the book, and the book stays alive as long as at least one friend has it. But sometimes, you want to know if the book is still available without actually borrowing it. That's where weak_ptr comes in—it lets you peek at the book without holding it.
Technically, weak_ptr does not increase the reference count of the object. It keeps a weak reference to the object managed by shared_ptr. This means it won't keep the object alive by itself. You can check if the object still exists and safely access it by converting the weak_ptr to a shared_ptr temporarily.
This mechanism is useful to avoid circular references, where two or more objects hold shared_ptr to each other, causing a memory leak because their reference counts never reach zero.
Example
This example shows how weak_ptr can observe an object managed by shared_ptr without owning it. It checks if the object is still alive before using it.
#include <iostream> #include <memory> int main() { std::shared_ptr<int> sp = std::make_shared<int>(42); // shared ownership std::weak_ptr<int> wp = sp; // weak_ptr observes sp std::cout << "Shared pointer count: " << sp.use_count() << "\n"; if (auto temp_sp = wp.lock()) { // try to get shared_ptr std::cout << "Value from weak_ptr: " << *temp_sp << "\n"; } else { std::cout << "Object no longer exists.\n"; } sp.reset(); // release shared_ptr ownership if (auto temp_sp = wp.lock()) { std::cout << "Value from weak_ptr after reset: " << *temp_sp << "\n"; } else { std::cout << "Object no longer exists after reset.\n"; } return 0; }
When to Use
Use weak_ptr when you want to refer to an object managed by shared_ptr without extending its lifetime. This is especially important to avoid memory leaks caused by circular references.
For example, in a tree or graph structure where parent and child nodes refer to each other, using shared_ptr in both directions can cause a cycle. Using weak_ptr for the backward or non-owning links breaks this cycle.
Also, weak_ptr is useful when caching objects or observing resources that might be deleted elsewhere, allowing safe access only if the object still exists.
Key Points
- weak_ptr does not own the object and does not increase reference count.
- It helps prevent circular references that cause memory leaks.
- You must convert
weak_ptrtoshared_ptrusinglock()before accessing the object. - If the object is deleted,
lock()returns an emptyshared_ptr. - Use
weak_ptrfor non-owning references in shared ownership scenarios.
Key Takeaways
weak_ptr holds a non-owning reference to an object managed by shared_ptr.shared_ptrs.weak_ptr to shared_ptr with lock() before use.weak_ptr does not affect the object's lifetime or reference count.weak_ptr for safe observation of shared objects without ownership.