Roadmap to becoming a developer in 2022
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

2.7 KiB

Weak Pointer

A weak_ptr is a type of smart pointer in C++ that adds a level of indirection and safety to a raw pointer. It is mainly used to break reference cycles in cases where two objects have shared pointers to each other, or when you need a non-owning reference to an object that is managed by a shared_ptr.

A weak_ptr does not increase the ownership reference count of the object it points to, which is a key difference between weak_ptr and shared_ptr. The control block associated with the object maintains two counts: one for the number of shared_ptrs (ownership count) and another for the number of weak_ptrs (weak count). The existence of weak_ptrs does not prevent the object from being deleted; the object is destroyed once the last shared_ptr that owns it is destroyed or reset, even if weak_ptrs are still referencing the object. However, the control block itself is not deallocated until both the ownership count reaches zero and the weak count also reaches zero, allowing weak_ptrs to safely detect whether the object has already been deleted.

To use a weak_ptr, you must convert it to a shared_ptr using the lock() function, which tries to create a new shared_ptr that shares ownership of the object. If successful, the object's reference count is increased and you can use the returned shared_ptr to safely access the object.

Here's an example of using weak_ptr:

#include <iostream>
#include <memory>

class MyClass {
public:
    void DoSomething() {
        std::cout << "Doing something...\n";
    }
};

int main() {
    std::weak_ptr<MyClass> weak;

    {
        std::shared_ptr<MyClass> shared = std::make_shared<MyClass>();
        weak = shared;

        if(auto sharedFromWeak = weak.lock()) {
            sharedFromWeak->DoSomething(); // Safely use the object
            std::cout << "Shared uses count: " << sharedFromWeak.use_count() << '\n'; // 2
        }
    }

    // shared goes out of scope and the MyClass object is destroyed

    if(auto sharedFromWeak = weak.lock()) {
        // This block will not be executed because the object is destroyed
    }
    else {
        std::cout << "Object has been destroyed\n";
    }

    return 0;
}

In this example, we create a shared_ptr named shared that manages a MyClass object. By assigning it to a weak_ptr named weak, we store a non-owning reference to the object. Inside the inner scope, we create a new shared_ptr named sharedFromWeak using weak.lock() to safely use the object. After the inner scope, the MyClass object is destroyed since shared goes out of scope, and any further attempt to create a shared_ptr from weak will fail as the object is already destroyed.