0

Recently I have met the std::enable_shared_from_this<T> template, which is the same as its Boost version.
So It describes the following sample code:

class Y: public enable_shared_from_this<Y>
{
public:

    shared_ptr<Y> f()
    {
        return shared_from_this();
    }
}

int main()
{
    shared_ptr<Y> p(new Y);
    shared_ptr<Y> q = p->f();
    assert(p == q);
    assert(!(p < q || q < p)); // p and q must share ownership
}

What is the reason creating the shared_ptr through f()?
Whats wrong with shared_ptr<Y> p(new Y);?

Community
  • 1
  • 1
Eduard Rostomyan
  • 7,050
  • 2
  • 37
  • 76
  • unnamed and invisible down voters, please consider putting a comment – Eduard Rostomyan May 08 '18 at 14:22
  • 1
    It wasn't me, but I'm not sure what your asking. You can use a new'd variable in a shared pointer. You need this instance method to get things sharing a refernce count: https://stackoverflow.com/questions/712279/what-is-the-usefulness-of-enable-shared-from-this – doctorlove May 08 '18 at 14:25
  • 1
    This is a poor example since you could just use `auto q = p;`. – François Andrieux May 08 '18 at 14:26
  • I understand, why cant the second shared_ptr be created using the first shared_ptr, without invoking shared from this. – Eduard Rostomyan May 08 '18 at 14:26
  • @EduardRostomyan It can. – François Andrieux May 08 '18 at 14:26
  • this example is from boost documentation @FrançoisAndrieux. I know that by that time auto was not introduced, but why cant we just create a shared ptr using the first one? – Eduard Rostomyan May 08 '18 at 14:27
  • 5
    @EduardRostomyan You don't need `shared_from_this` here. `std::shared_ptr q = p;` is fine here. `shared_from_this` is only relevant when you need a `shared_ptr` to an instance that is already owned by a `shared_ptr` but you can't access a copy of that pointer directly. – François Andrieux May 08 '18 at 14:28
  • One school of thought is that objects should not be self-aware that they are contained in a shared_ptr. There are also caveats, such as UB or (C++17) exception if done incorrectly. That being said, I find it helpful when porting from C#, because C++ shared_ptr has similar semantics to C# references. – Eljay May 08 '18 at 14:31
  • @FrançoisAndrieux, thats all clear now! thx – Eduard Rostomyan May 08 '18 at 14:32
  • 1
    @Eljay "_One school of thought is_" another "school" says that if an object is "self aware", it should be a good reason, because the design implies that, it should be an invariant of the class (let's call it `managed`), and then `shared_from_this` is fragile and insufficient, and you should provide a factory function to make the object (`make_managed`) and not allow the construction by `new` or an automatic or static object or a member. – curiousguy Jun 08 '18 at 01:06

2 Answers2

3

Whats wrong with shared_ptr p(new Y);?

There is nothing wrong with it, only issue you may not have it inside a member of class Y and sometimes you want a member to return std::shared_ptr to itself. std::shared_ptr<Y>( this ) is an obviously wrong way to create one.

I wonder if such example can make things clearer and would be still simple enough:

std::shared_ptr<Y> Y::getObject() 
{
     return some_condition ? shared_from_this() : std::make_shared<Y>( somedata );
}
Slava
  • 43,454
  • 1
  • 47
  • 90
3

The point of shared_from_this is to allow you to get a shared_ptr when you don't already have access to one. It's pointless in your example because your example is too simplified. Imagine there's some function that only gets a Y* or a Y&, and it needs to share ownership with someone. This frequently happens for members of Y, since members only have access to this.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982