Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I have a reference and want to call a function that takes boost::shared_ptr

I have a reference to an object and want to call a function that takes a boost::shared_ptr of this object. If I build a boost::shared_ptr to make the call when my boost::shared_ptr is canceled from the stack than the object is canceled too! This is exactly what happens when I run this code:

double f(boost::shared_ptr<Obj>& object)
{
  ...
}

double g(Obj& object)
{
  boost::shared_ptr<Obj> p(&object);
  double x = f(p);
  ...
}

Is there a way to make it work? How can I create in g() a boost::shared pointer that leaves my object alive at the end? I think I have to connect it to the reference counting machinery of other shared pointers that already point to object... but how?

Even if I make it work do you think this way of doing is bad design? What is the best practice to solve this kind of problems? In my code I have objects and methods that work both with shared pointer and references and I cannot work only with these or those...

like image 501
martino Avatar asked Nov 21 '25 10:11

martino


1 Answers

A function that takes a shared_ptr is saying something about what it does. It is saying, "I want to potentially claim shared ownership of this object". If this is not true, then it is a poorly written function and shouldn't be taking a shared_ptr at all.

A function which takes a value by non-const reference to an object means that the function can modify the object, but cannot claim ownership. If you don't own something, you also can't give ownership to someone else.

Now, you could perform this trick of using an empty deleter function:

void EmptyDeleter(Obj *) {}

double g(Obj& object)
{
  boost::shared_ptr<Obj> p(&object, EmptyDeleter);
  double x = f(p);
  ...
}

However, you are now lying to f. It doesn't own object; it can't own object. It is very possible that object is a stack object that may disappear any time after f completes. If f were a member of a class, it might store the shared_ptr in a member variable. At which point, it would then have a shared_ptr to a dead object. This is exactly the sort of thing that shared_ptrs are intended to prevent.

The correct answer is for either f to not take its argument by shared_ptr (use non-const reference or non-const pointer if it is modifiable, and const& if it is not modifiable), or for g to take its argument by shared_ptr.

like image 69
Nicol Bolas Avatar answered Nov 23 '25 23:11

Nicol Bolas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!