Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I call a private destructor from a shared_ptr?

I have a resource_manager class which maintains a std::vector<boost::shared_ptr<resource> > internally. resource_manager is a friend class of resource. I want resources to only be created/deleted by resource_manager, so I made its constructors private (which works ok).

However, if I make the destructor private, the code doesn't compile because the destructor is called by boost::shared_ptr, which is not a friend of resource. I am thinking of enforcing the "do not delete by clients" rule by only returning only const resource* from the resource_manager, but somehow I am not satisfied with the security this method provides (what if a client somehow happens across a pointer to non-const?)

Apart from the obvious solution of not using shared_ptr, do you have any workaround / better solution to my problem?

like image 891
Dan Nestor Avatar asked Nov 20 '11 15:11

Dan Nestor


People also ask

How can I call a destructor from a shared pointer?

You can release the ownership of the object by calling reset() on the shared_ptr. If that is the last one holding the pointer, the shared_ptr's deleter member will be used to destroy the object.

What does shared_ptr get () do?

A shared_ptr can share ownership of an object while storing a pointer to another object. This feature can be used to point to member objects while owning the object they belong to. The stored pointer is the one accessed by get(), the dereference and the comparison operators.

What happens when shared_ptr goes out of scope?

All the instances point to the same object, and share access to one "control block" that increments and decrements the reference count whenever a new shared_ptr is added, goes out of scope, or is reset. When the reference count reaches zero, the control block deletes the memory resource and itself.

Should I use Unique_ptr or shared_ptr?

Use unique_ptr when if you want to have single ownership(Exclusive) of resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another. Use shared_ptr if you want to share ownership of resource .


2 Answers

You can pass a custom deleter to the shared pointer. So just create a deleter functor or function (up to you) which in turn is a friend of your class:

class Secret
{
  ~Secret() { }
  friend class SecretDeleter;
  friend void SecretDelFunc(Secret *);
};

class SecretDeleter
{
public:
  void operator()(Secret * p) { delete p; }
};

void SecretDelFunc(Secret * p) { delete p; }

std::shared_ptr<Secret> sp1(new Secret, SecretDeleter());
std::shared_ptr<Secret> sp2(new Secret, SecretDelFunc);
like image 192
Kerrek SB Avatar answered Oct 05 '22 23:10

Kerrek SB


Perhaps declare shared_ptr<resource> as a friend? shared_ptr doesn't call the constructor, and should only destruct if your resource manager releases the pointer before all clients have destroyed their shared_ptrs. This won't allow clients to break the protection, but will allow clients to keep a resource alive against the resource_manager's "will."

like image 36
01d55 Avatar answered Oct 05 '22 23:10

01d55