Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalidate all shared ptrs toward a specific managed object

Is it possible, in C++11, to have an object managed by several std::shared_ptrs. I want to delete the object via one std::shared_ptr and have the other shared_ptrs invalidated (set empty or null), is this possible? If not, what is the best method to inform all other "references" (in a liberal use of the word) that the object is no longer valid?

like image 672
shane Avatar asked Jan 19 '17 14:01

shane


People also ask

Can shared_ptr be Nullptr?

A null shared_ptr does serve the same purpose as a raw null pointer. It might indicate the non-availability of data. However, for the most part, there is no reason for a null shared_ptr to possess a control block or a managed nullptr .

When to pass shared_ ptr?

Use this option when the implied or explicit code contract between the caller and callee requires that the callee be an owner. Pass the shared_ptr by reference or const reference. In this case, the reference count isn't incremented, and the callee can access the pointer as long as the caller doesn't go out of scope.

Is shared_ptr thread safe?

std::shared_ptr is not thread safe. A shared pointer is a pair of two pointers, one to the object and one to a control block (holding the ref counter, links to weak pointers ...).

What are shared pointers in C++?

Shared pointers in C++ In C++, a shared pointer is one of the smart pointers. The shared pointer maintains a reference count which is incremented when another shared pointer points to the same object. So, when the reference count is equal to zero (i.e., no pointer points to this object), the object is destroyed.


2 Answers

To do this, the other shared_ptrs have to be replaced with weak_ptrs. The shared_ptr that does the deletion is the one actually manages the lifetime of the object in this scenario. It's worthwhile at this point to figure out if you really need shared ownership semantics. In general, if you find yourself trying to do something the interface doesn't let you do, that's an indication that you need something with different semantics.

Alternatively, if you really can't manage the object's lifetime from one place, you can use shared_ptr<unique_ptr<T>>, but this is more cumbersome (not to mention slower) and is better to avoid. Here you would delete the object by resetting the inner unique_ptr.

like image 70
Dan Avatar answered Sep 28 '22 03:09

Dan


Here is a good example of weak_ptr and to be informed when all other "references" is no longer valid.

#include <iostream>
#include <memory>

std::weak_ptr<int> gw;

void f()
{
    std::cout << "use_count == " << gw.use_count() << ": ";
    if (auto spt = gw.lock()) 
    { // Has to be copied into a shared_ptr before usage
        std::cout << *spt << "\n";
    }
    else 
    {
        std::cout << "gw is expired\n";
    }
}

int main()
{
    {
        std::shared_ptr<int> sp = std::make_shared<int>(42);
        gw = sp;
        f();
    }
    f();
}

Output:
use_count == 1: 42
use_count == 0: gw is expired

like image 30
Rama Avatar answered Sep 28 '22 03:09

Rama