What is the need for enable_shared_from_this? [duplicate]

时光怂恿深爱的人放手 提交于 2019-12-03 15:35:32

A shared_ptr manages two different things. It has a pointer to its data, and a pointer to a reference counting block.

The reference counting block has a strong counter, a weak counter and a destroy operation in it.

When you std::shared_ptr<X>(pX), it creates a new reference counting block that, when the last (strong) reference goes away, it deletes the pX object.

The same thing happens when you std::shared_ptr<X>(this).

So, if you wrap an object in std::shared_ptr in two different spots, you have to different reference counting blocks, and they both want to destroy the object when they go away.

enable_shared_from_this<X> changes how this works. When you create a shared pointer to an object inheriting from it, it stores a std::weak_ptr<X> inside the enable_shared_from_this<X>. A weak pointer stores a pointer to the above reference counting block, but only "holds" a weak reference (not a strong one).

Then, when you call shared_from_this(), it does a .lock() on that weak pointer and returns a shared pointer using the reference counting block of the old one created (as stored by the weak_ptr).

Now, the above is an example implementation of what it could do: the standard mandates behavior, not implementation, and the weak_ptr is a possible way to implement it. Similarly, the reference counting block detail is just an example implementation.

The core issue is that two independent shared pointers wrapping the same pointer will try to independently manage the pointer's lifetime. enable_shared_from_this makes the first smart pointer's reference counting block be used by later shared_from_this() return values.

Short answer: you need enable_shared_from_this when you need to use inside the object itself existing shared pointer guarding this object.

Out of the object you can simply assign and copy a shared_ptr because you deal with the shared_ptr variable as is. But when you are in one of the class members then if you need to use a shared pointer pointing to self object (instead of ordinary this) and there is no such shared pointer in arguments of that method then shared_from_this() is what will help you. Using std::make_shared(this) is absolutely unsafe as you can not have two shared pointers on the same object. While, shared_from_this() is safe because it uses weak_ptr to "resolve" already existing shared_ptr.

To be able to use shared_from_this() you must first use enable_shared_from_this in your class definition which adds a shared_from_this() method to your class.

Note, shared_from_this() can not be used in the class constructor! At that time the shared_ptr does not exist yet, so the shared_from_this() can't resolve any exisiting pointers.

And when and why one can need a shared pointer to this instead of just this it is quite other question. For example, it is widely used in asynchronous programming for callbacks binding.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!