Advertisement

use of shared_ptr

Started by October 29, 2017 07:15 PM
19 comments, last by ferrous 6 years, 10 months ago

Hi,

   I have been trying to use shared_ptr but after searching the net and reading example, I still don't understand how to use std::shared_ptr?

   Say, I have a class -


class foo
{
   public:
      foo();
      ~foo();
      void init();
}

   Now I want to use this in another class -


class useme
{
   public:
      useme();
      ~useme();
     void init();
   private:
      std::shared_ptr<foo> f1;
      std::list<shared_ptr<foo>> foolist;
}

   In init() method, how do I create the f1 and push_back it into foolist?

I tried like this -

foolist.push_back(std::shared_ptr<foo>(new foo()));

or

f1 = std::make_shared<foo>(new foo());

foolist.push_back(f1);

Any help will be appreciated. Thanks in advance.

The parameters for std::make_shared are the arguments for the template type's constructor, you should not be using new.

Advertisement

Ok, to delete the container I only need to clear foolist, like - foolist.clear()  and the f1 will also be cleared automaticaly? Or I should make the f1 null, like - f1 = 0? Or I should iterate through the list and delete each element before closing the application?

It's not clear why you have both f1 and foolist - if you're creating a new object and storing it, you usually only need to store it in one place.

Once you have your shared_ptr to whatever, once all the copies of that pointer are deleted, the object is deleted as well - so you never have to call `delete` on it directly.

If your list is cleared or destroyed, all the shared_ptrs in it are also destroyed, and so if those were the last ones to refer to your object, the object gets deleted properly. You don't have to clear shared_ptr or set them to null before destroying them.

f1 is the pointer for the current object selected and the foolist is the container of the all objects available. So I was a bit confused whether to delete or set null the f1 pointer after deleting or clearing the foolist.

shared_ptr implies ownership semantics over the pointer it contains. It makes sense, looking at your code, to maintain ownership within foolist. It doesn't make sense to also maintain ownership in f1.  The list can be said to 'own' the objects, but f1 is just an indicator, a place-marker, which probably has no controlling interest in the lifetime of an object. I would prefer to use a weak_ptr there instead.

Advertisement

Ok, so I should change shared_ptr to weak_ptr? And yes, I don't want ownership in f1, that's why I decided to use shared_ptr. Because I was unsure that f1 was freed properly before closing the application. I am only clearing the foolist.

Any allocated memory in a shared_ptr in your example, f1, is freed automatically when the class goes out of scope.

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

Ok, thanks for the reply and help.

Yes, I would make f1 a weak_ptr. Keep the ones stored in foolist as shared, then whenever an object is selected just set f1 from the shared_ptr in foolist. Before using f1, you can call expired() to see if it is valid. If the object stored in foolist was removed/deleted and all shared_ptr copies of it are gone, then expired() will return true meaning the object is gone. You can call lock() on a weak_ptr to obtain a shared_ptr from the weak_ptr. As long as the shared_ptr object created by lock() is around, then the object will not be deleted, even if it is removed from foolist. As soon as all shared_ptrs to an object are gone, including any obtained from calling lock() on the weak_ptr, then the object is automatically deleted, and any weak_ptr that point to it will return expired.

This topic is closed to new replies.

Advertisement