0
0
CppConceptBeginner · 3 min read

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.

cpp
#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;
}
Output
Shared pointer count: 1 Value from weak_ptr: 42 Object no longer exists after reset.
🎯

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_ptr to shared_ptr using lock() before accessing the object.
  • If the object is deleted, lock() returns an empty shared_ptr.
  • Use weak_ptr for non-owning references in shared ownership scenarios.

Key Takeaways

weak_ptr holds a non-owning reference to an object managed by shared_ptr.
It prevents memory leaks by breaking circular references between shared_ptrs.
Always check if the object exists by converting weak_ptr to shared_ptr with lock() before use.
weak_ptr does not affect the object's lifetime or reference count.
Use weak_ptr for safe observation of shared objects without ownership.