Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it correct to return null shared_ptr?

For example, there is a function that finds an object and returns shared_ptr if object is found, and must indicate somehow that no object was found.

std::vector<std::shared_ptr> Storage::objects;

std::shared_ptr<Object> Storage::findObject()
{
  if (objects.find)
  {
    return objects[x];
  }
  else
  {
    return nullptr;
  }
}

std::shared_ptr<Object> obj = Storage::findObject();
if (obj)
{
  print("found");
}
else
{
  print("not found");
}
  1. Is it correct to return shared_ptr implicitly initialized with nullptr like in upper example? It will work, but can be it done this way? Or should I return shared_ptr default constructed instead?

  2. What in case it would be weak_ptr? What is proper way to check that empty weak_ptr has been returned? by weak_ptr::expired function or are there other ways? If checking by weak_ptr::expired is the only way then how can I distinguish that function returned empty pointer, or object was just deleted(multi-thread environment)?

like image 976
John Lock Avatar asked May 15 '16 05:05

John Lock


People also ask

Can a shared_ptr be null?

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 .

What is an empty shared_ptr?

Empty shared_ptr can be constructed with default constructor or with constructor that takes nullptr . Non-empty null shared_ptr has control block that can be shared with other shared_ptr s. Copy of non-empty null shared_ptr is shared_ptr that shares the same control block as original shared_ptr so use count is not 0.

When should you use shared_ptr?

So, we should use shared_ptr when we want to assign one raw pointer to multiple owners. // referring to the same managed object. When to use shared_ptr? Use shared_ptr if you want to share ownership of a resource.

What happens when shared_ptr goes out of scope?

The smart pointer has an internal counter which is decreased each time that a std::shared_ptr , pointing to the same resource, goes out of scope – this technique is called reference counting. When the last shared pointer is destroyed, the counter goes to zero, and the memory is deallocated.


1 Answers

Is it correct to return shared_ptr implicitly initialized with nullptr like in upper example?

Yes, it is correct to initialize shared_ptr with nullptr. It is also correct to assign nullptr to shared_ptr.

Or should I return shared_ptr default constructed instead?

You can do this in both ways:

  1. returning shared_ptr initialized with nullptr

    return shared_ptr<Object>(nullptr);
    
  2. returning shared_ptr default constructed.

    return shared_ptr<Object>();
    

Both ways are correct and both have the same effect. You can use whatever way you want.

What in case it would be weak_ptr? What is proper way to check that empty weak_ptr has been returned? by weak_ptr::expired function or are there other ways?

weak_ptr becomes nullptr (expires) whenever the last shared_ptr associated with object is destroyed.

The proper way to work with weak_ptr is to convert it to shared_ptr with lock method, and then to work with created shared_ptr. In that case your weak_ptr will no expire until you have that new shared_ptr. If you don't convert weak_ptr into shared_ptr, your weak_ptr may expire at any moment.

And yes, before working with newly created shared_ptr, you must check that it isn't null, because weak_ptr may had been expired before you created shared_ptr with lock method.

std::weak_ptr<Object> Storage::findObject();

...

std::weak_ptr  <Object> weak   = Storage::findObject();
std::shared_ptr<Object> shared = weak.lock();
if (shared) // check that weak was not expired when we did "shared = weak.lock()"
{
    // do something with shared, it will not expire.
}
like image 68
anton_rh Avatar answered Sep 20 '22 14:09

anton_rh