How to Use weak_ptr in C++: Syntax, Example, and Tips
In C++,
weak_ptr is used to hold a non-owning reference to an object managed by shared_ptr. It helps avoid circular references by not increasing the reference count. You create a weak_ptr from a shared_ptr and use lock() to access the object safely.Syntax
The weak_ptr is declared as std::weak_ptr<T>, where T is the type of the object. You initialize it from a shared_ptr. To access the object, call lock() which returns a shared_ptr if the object still exists, or an empty shared_ptr if it was deleted.
- std::weak_ptr<T> wptr; - declares a weak pointer.
- wptr = shared_ptr; - assign from shared pointer.
- auto sptr = wptr.lock(); - get shared pointer safely.
cpp
std::weak_ptr<T> wptr; // declare weak_ptr wptr = shared_ptr; // assign from shared_ptr if (auto sptr = wptr.lock()) { // use sptr safely } else { // object no longer exists }
Example
This example shows how weak_ptr can observe an object managed by shared_ptr without owning it. When the last shared_ptr is destroyed, the object is deleted and weak_ptr::lock() returns empty.
cpp
#include <iostream> #include <memory> int main() { std::shared_ptr<int> sptr = std::make_shared<int>(42); std::weak_ptr<int> wptr = sptr; // weak_ptr observes sptr std::cout << "Shared pointer count: " << sptr.use_count() << "\n"; if (auto locked = wptr.lock()) { std::cout << "Value via weak_ptr: " << *locked << "\n"; } else { std::cout << "Object no longer exists.\n"; } sptr.reset(); // destroy shared_ptr, object deleted if (auto locked = wptr.lock()) { std::cout << "Value via weak_ptr: " << *locked << "\n"; } else { std::cout << "Object no longer exists after reset.\n"; } return 0; }
Output
Shared pointer count: 1
Value via weak_ptr: 42
Object no longer exists after reset.
Common Pitfalls
Common mistakes when using weak_ptr include:
- Trying to dereference
weak_ptrdirectly without callinglock(), which is invalid. - Not checking if
lock()returns a validshared_ptrbefore use, leading to crashes. - Using
weak_ptrwhen ownership is needed; it does not keep the object alive.
Always use lock() and check the result before accessing the object.
cpp
std::weak_ptr<int> wptr; // Wrong: dereferencing weak_ptr directly // std::cout << *wptr << std::endl; // ERROR // Right way: auto sptr = wptr.lock(); if (sptr) { std::cout << *sptr << std::endl; } else { std::cout << "Object expired" << std::endl; }
Quick Reference
- std::weak_ptr<T>: Non-owning smart pointer to
T. - lock(): Returns
shared_ptr<T>if object exists, else empty. - use_count(): Returns number of
shared_ptrowners. - Use
weak_ptrto break circular references.
Key Takeaways
Use std::weak_ptr to hold a non-owning reference to a shared object without increasing its reference count.
Always call lock() on weak_ptr and check if the returned shared_ptr is valid before accessing the object.
weak_ptr helps prevent memory leaks caused by circular references between shared_ptrs.
Do not dereference weak_ptr directly; it does not own the object and may be expired.
Resetting all shared_ptr owners deletes the object, making weak_ptr expired.