Question

I want to use shared_from_this as follows:

class example;    // Forward declaration. 
void bar(boost::shared_ptr<example>);

class example : public boost::enabled_shared_from_this<example>
{
    void foo () 
    {
        bar(shared_from_this(this));
    }
};

My problem is that I don't want to force example.foo() to be called only with example objects that are owned by a shared_ptr. For example I want to allow the following:

example * p = new example;
p->foo(); 

but this seems to be an error, since p isn't owned by a shared_ptr. Please correct me if I'm mistaken.

In case I'm not mistaken, how can I get this over?

Was it helpful?

Solution

My problem is that I don't want to force example.foo() to be called only with example objects that are owned by a shared_ptr.

How do you expect to pass a shared_ptr to bar if the object isn't owned by a shared_ptr? Do you want to pass a n empty shared_ptr?

You could do nasty things with the aliasing constructor of shared_ptr but I wouldn't recommend it.

Please correct me if I'm mistaken.

You're not mistaken, enable_shared_from_this<T>::shared_from_this() has a precondition that at least one shared_ptr owns the object.

In case I'm not mistaken, how can I get this over?

There is no portable way to avoid that, because it's a precondition, and you must not violate preconditions, however this might "work" (for some value of work):

void example::foo () 
{
  shared_ptr<example> ptr;
  try {
    ptr = shared_from_this(this);
  } catch (boost::bad_weak_ptr const&) {
  }
  bar(ptr);
}

OTHER TIPS

When deriving your class T from std::enable_shared_from_this<T>, you allow for an object that is managed by a shared_ptr<T> to generate additional shared_ptr<T> instances - so you work around the bad habit of doing

return std::shared_ptr<T>(this); // bad!

which usually leads to problems with double deletion (because the this pointer is already owned by a different std::shared_ptr<T>). The ownership problem displayed here is the same your current problem breaks down to:

Quoted from here:

A common implementation for enable_shared_from_this is to hold a weak reference (such as std::weak_ptr) to this. The constructors of std::shared_ptr can detect presence of a enable_shared_from_this base and share ownership with the existing std::shared_ptrs, instead of assuming the pointer is not managed by anyone else.

When you sign a contract, and you did (though as mentioned in the comments above not with deriving, but with using shared_from_this()), better keep it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top