Reputation: 5726
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?
Upvotes: 0
Views: 300
Reputation: 8975
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.
Upvotes: 2
Reputation: 171501
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);
}
Upvotes: 3