1

I am looking into the boost documentation for shared_ptr and enable_shared_from_this and I can not figure out practical use of enable_shared_from_this.

Below is my understanding of enable_shared_from_this (example copied from What is the usefulness of `enable_shared_from_this`?).

class Y: public enable_shared_from_this<Y>
{
    public:
      Y(): count(3){}
      shared_ptr<Y> f()
      {
         return shared_from_this();
      }
      int count;
}

int main()
{
    shared_ptr<Y> p(new Y);
    shared_ptr<Y> q = p->f();
    cout << "\n Count from P is " << p1->count;
    cout << "\n Count from q is " << q1->count;
}

So, now we have a shared pointer q which points to the same object owned by p (new Y) and the object gets destroyed when both p and q go out of scope. And both the print statements above will print 3 as the count.

Now, I can achieve the same thing without the use of enable_shared_from_this by doing below.

class Y
{
    public:
      Y(): count(3){}
      int count;
}

int main()
{
    shared_ptr<Y> p(new Y);
    shared_ptr<Y> q(p);
    cout << "\n Count from P is " << p1->count;
    cout << "\n Count from q is " << q1->count;
}

Even in the above example both P and Q point to the same object and will print 3.

So, what benefit am I getting by using the enable_shared_from_this?

Community
  • 1
  • 1
Dev
  • 1,529
  • 4
  • 24
  • 36
  • You didn't get the mention of `count` right in the sample you're pointing to. The answerer meant the internal `shared_ptr` count. – πάντα ῥεῖ Dec 01 '13 at 11:10
  • 3
    A crazy thought: `shared_from_this` is some kind of "adult version" of old C++ code that uses `delete this`; i.e. it appeals to the same dirty minds. – Kerrek SB Dec 01 '13 at 11:13
  • @g-makulik - I believe my question is different to the previous question already asked in SO. My question is that both examples above provide shared ownership to the object Y. In that case, why should we use enable_shared_from_this? what benefit is enable_shared_from_this providing compared to 2nd example? – Dev Dec 01 '13 at 11:20
  • @devana It's very well explained there why it's needed and useful, and I don't see your question adding any value above the other one. It's not just rewording and changing the samples slightly, that make up a new question. – πάντα ῥεῖ Dec 01 '13 at 11:24
  • @KerrekSB hat-tip https://twitter.com/sehetw/status/519773714003402752 – sehe Oct 08 '14 at 08:58

2 Answers2

9

shared_from_this is a very special animal. Usually, you should separate responsibilities: A class does one thing, and one thing only. Owning a resource is such a responsibility, so a class should either own a resource and do nothing else, or do something else but not own a resource.

The use for shared_from_this is when this principle is violated, and a class knows that it is owned by a shared pointer. In that case, you need a way to get at that ambient shared pointer that is owning you. You cannot simply say shared_ptr<T>(this), because that would create a new owner, rather than share ownership with the existing owner.

To communicate from the class to its ambient owner, you need to derive from enable_shared_from_this, and then use shared_from_this to produce a new shareholder.

(This works practically by adding a weak_ptr<T> member to the class, and upon creation of the ambient shared pointer, that weak pointer is set to observe the shared pointer. So shared_from_this is a simple lock() invocation on the weak pointer.)


Here's an example to clarify the usage:

auto x = std::make_shared<T>();
f(*x);

// ...

void f(T const & t)
{
    auto y = t.shared_from_this();
    // ...
}

Inside f, we don't see the owner of t immediately, but shared_from_this brings it out.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • My understanding is that 2nd example provided the question gives the same shared ownership as provided by enable_shared_from_this in the 1st example. Am I correct in thinking in that? If both the examples provide shared ownership to the object, why should i use enable_shared_from_this ? – Dev Dec 01 '13 at 11:18
  • 1
    @devana: Of course, but in the second example you're cheating and you already have `p`. `shared_from_this` is for situations where you only have `*p` (or `p->`)! I added an example. – Kerrek SB Dec 01 '13 at 11:19
  • Thanks for that 2nd example. That makes it very clear. – Dev Dec 01 '13 at 11:26
  • Downvoter, care to explain your objection? – Kerrek SB Dec 10 '13 at 09:14
0

The benefit is a matter of structuring. In your example, the guy who owns q might not know anything about, or have access to, the guy who owns p. It's sometimes easier to get another shared_ptr to the same instance from the type (in this case Y).

That said, I personally never use enable_shared_from_this. It's in the same boat as singletons as far as I'm concerned.

David
  • 27,652
  • 18
  • 89
  • 138
  • 2
    `shared_from_this` is an important idiom, when creating anonymous functors bound to `this` and passing them to an asynchronous subsystem, for instance. – Igor R. Dec 01 '13 at 12:04