How the boost library enable_shared_from_this works

Source: Internet
Author: User
Scenario : When the class object is managed by shared_ptr, you need to pass the current class object as a parameter to other functions in the function defined by the class itself. In this case, you need to pass a shared_ptr, otherwise, you cannot maintain the semantics of shared_ptr managing this class Object ( Because there is a raw pointer pointing to this class object, and shared_ptr does not count this reference of the class object, it is very likely that shared_ptr has released the Class Object resource, the called function is still using class objects -- obviously, this will certainly produce errors ).
Curious about the implementation of this template class.
First, let's see how to use it. :
For a class A, when we want to use shared_ptr to manage its class objects, we also need to put the Class Object shared_ptr ( Why don't we use normal pointers? When we use smart pointers to manage resources, we must use smart pointers in a unified manner, instead of using raw pointer in some places, otherwise, intelligent pointer semantics cannot be maintained, resulting in various errors. When passed to other functions, Class A can inherit from enable_shared_from_this:
Class A: Public boost: enable_shared_from_this <A> { };
Then, use the shared_from_this function to obtain the shared_ptr pointing to the class object itself in Class.
A very representative example:
Http://www.boost.org/doc/libs/1_39_0/doc/html/boost_asio/tutorial/tutdaytime3/src.html
In addition, the shared_ptr section of beyond the C ++ standard library also provides simple and clear examples.
Implementation Principle :
The first thing to consider is that the class object itself cannot store the shared_ptr of the class object itself. Otherwise, the Class Object shared_ptr will never be 0, so that these resources will never be released unlessProgramEnd.
Second, class objects must be allocated by external functions through some mechanism, and are immediately handed over to shared_ptr for management ( Re-emphasize: resources managed for shared_ptr must be handed over to shared_ptr upon allocation. ). In the future, where you want to share the class object, you must use this shared_ptr as the right value to construct and generate or copy to generate another shared_ptr for sharing.
With the above two restrictions, we need to achieve our goal ( That is, the shared_ptr of the class object is used inside the class object. ) There are two solutions:
1. The external shared_ptr of the Class Object is passed to the class as a function parameter and needs to reference the function of the class object itself-obviously, this method is ugly and not all situations are feasible ( For example, it cannot be in the scope invisible to the external shared_ptr. );
2. The class object itself stores certain information and generates a temporary shared_ptr when it needs its own shared_ptr.
Obviously, the key to being more elegant (for users) is how to store information?
By the way, weak_ptr!
Actually, boost is implemented in this way.
But now the question is: when will this weak_ptr be initialized? Because shared_ptr for managing this object is not generated when the class object is generated.
Boost 1.39.0 is implemented as follows:
First generate class A: calls the constructor of enable_shared_from_this (defined as protected) and the constructor of Class A in turn. When you call the enable_shared_from_this constructor, The weak_ptr defined in enable_shared_from_this is initialized (the default constructor is called). In this case, the weak_ptr is invalid (or does not point to any object ).
Next, the external program initializes a shared_ptr by using the pointer to the Class A object as the initialization parameter.
Now let's take a look at how shared_ptr is initialized. shared_ptr defines the following constructor:
Template <class Y>   Explicit shared_ptr (y * P): Px (P), Pn (P)   {   Boost: detail: sp_enable_shared_from_this (this, P, P );   }
It is calledBoost: detail: sp_enable_shared_from_this:
Template <Class X, class y, class T>  Inline void sp_enable_shared_from_this (boost: shared_ptr <x> const * ppx,  Y const * py, boost: enable_shared_from_this <t> const * PE) {   If (PE! = 0)   {   Pe-> _ internal_accept_owner (ppx, const_cast <y *> (Py ));   } }
It also calls the _ internal_accept_owner of enable_shared_from_this:
Template <Class X, class Y> void _ internal_accept_owner (shared_ptr <x> const * ppx, y * Py) const   {   If (weak_this _. Expired ())   {   Weak_this _ = shared_ptr <t> (* ppx, Py );   }   }
Here, we copy and assign values to weak_ptr, the member of enable_shared_from_this, so that the entire weak_ptr is used as a class object.An observer of shared_ptr.
In this case, when the class object itself needs its own shared_ptr, we can generate one from this weak_ptr.
It turns out that.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.