1

If I want to return a shared_ptr for class A, I should use shared_from_this() feature. But I think this will work after I defined a shared_ptr for A already. So if another place wants a shared_ptr I just use the one I made. I wonder when to use shared_from_this().

sample code:

class A : public enable_shared_from_this<A> {
public:
    int a = 0;
    shared_ptr<A> get_this() {
        return shared_from_this();
    }
};

int main() {
    shared_ptr<A> ptr_a(new A);
    cout << ptr_a.use_count() << endl;
    shared_ptr<A> ptr_b = ptr_a->get_this(); 
    // if somewhere else wants a ptr I just use, shared_ptr<A> ptr_b = ptr_a; after pass it 
    // into a function, what situation should i use shared_from_this() for instead ???
    cout << ptr_a.use_count() << endl;
    cout << ptr_b.use_count() << endl;
}
  • 1
    You should use it when you need it and it's convenient. If you don't feel a need to use it, then don't. It's rarely needed. – eerorika Nov 17 '21 at 03:37
  • I think the question of when to use `shared_from_this` is good, but your understanding is a little bit off. You don't _need_ to use `shared_from_this` just to get a `shared_ptr` if you already have one. `shared_from_this` exists as a mechanism to get the `shared_ptr` of itself from _inside_ the class -- which can be useful for some cases like asynchronous message callbacks. Barring cases like that, you probably won't need to use it at all – Human-Compiler Nov 17 '21 at 03:46
  • @Human-Compiler Already changed my question to your suggestion. And your answer give me a hint when I see "get the shared_ptr of itself from inside the class". Thx a lot. – Yacheng Liu Nov 17 '21 at 03:56
  • `shared_ptr` is much more frequently / broadly used than is `shared_from_this`. `shared_from_this` is sometimes used in multi-threaded programming with relatively complex designs. For reference, see [this](https://www.nextptr.com/tutorial/ta1414193955/enable_shared_from_this-overview-examples-and-internals) post on enable_shared_from_this - overview, examples, and internals. – aafulei Nov 17 '21 at 04:10
  • @aafulei Very useful information and link in your reply, very appreciate. – Yacheng Liu Nov 17 '21 at 06:13

1 Answers1

3

You appear to have a misunderstanding about shared_ptr and shared_from_this.

You don't need to use shared_from_this in order to retrieve a shared_ptr if you already have one. In your example, you could just do:

auto ptr_a = std::make_shared<A>();
auto ptr_b = ptr_a;

However, there are cases where a design requires that a class be aware of its shared lifetime -- and must be able to retrieve a shared_ptr to itself. In such a case, you can't simply do: std::shared_ptr<A>{ this } because this would be producing a new shared_ptr node that is tracking the pointer of this -- which could result in a bad/double deletion.

shared_from_this() solves this by allowing the internals of the class to be able to retrieve safe shared_ptr object to the object that was allocated. In my experience, this pattern is most common with asynchronous callback handlers. For example:

auto A::do_something_async() -> void
{
    auto self = shared_from_this();
    std::thread{[self]{
        // do something long-living with 'self'
    }}.detach();
}

Note: I am not advocating for this style of code; just that this is a possible use for it. In general I find it better to design classes such that it never relies on knowing its own lifetime.

Human-Compiler
  • 11,022
  • 1
  • 32
  • 59