std::weak_ptr


Concept: weak pointers

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.

Key Characteristics of std::weak_ptr

Example 1: Basic Usage

#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;
}

Explanation:

Example2: Break Circular References

#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;
}

Explanation:

Example 3: Monitoring an Expensive Resource

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


include

include

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 globalWeakPtr;

void monitorResource() { if (std::shared_ptr resPtr = globalWeakPtr.lock()) { resPtr->useResource(); } else { std::cout << "Resource is no longer available" << std::endl; } }

int main() { { std::shared_ptr resPtr = std::make_shared(); globalWeakPtr = resPtr; // Create a weak reference to the resource

    monitorResource();  // Resource is available
}

// After resPtr goes out of scope, the resource is released

monitorResource();  // Resource is no longer available

return 0;

} ```

Explanation:

Summary

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.

Previous Page | Course Schedule | Course Content