Boost source code learning --- shared_ptr.hpp

Source: Internet
Author: User

Recently, I am looking at the boost Library source code. The boost library has powerful functions, but its source code is too much. It is too time-consuming to read it carefully. After all, there are other things to learn, so I decided to skip the chapters I was interested in and record their design ideas and hard-to-understand points.

Shared_ptr is the most valuable smart pointer in boost. It encapsulates an original ecological pointer and a reference counter, which is a class shared_count. Shared_ptr supports comparison operations and reloads operator <. Therefore, it can be used for set and map operations.

Use the *** _ pointer_cast-defined function to convert the shared_ptr pointer (the shared_ptr <t> type is returned ), if static_cast and reinterpret_cast are used, shared_ptr cannot correctly manage pointers.

Template <class T> class shared_ptr {PRIVATE: // Borland 5.5.1 specific workaround typedef shared_ptr <t> this_type; public: typedef typename boost: detail: sp_element <t> :: type element_type; // There are multiple constructors below. To adapt to different situations, // The default constructor uses PX as the pointer and Pn as the counter (it is a class shared_count, its default constructor sets its value to 0) shared_ptr () boost_no1_t: Px (0), Pn () // never throws in 1.30 + {}# if! Defined (partition) shared_ptr (boost: detail: sp_nullptr_t) boost_no1_t: Px (0), Pn () // never throws {} # endif // use the Y type for initialization, Y and T may be different types of template <class Y> explicit shared_ptr (y * P): Px (P), Pn () // y must be complete {boost: detail:: sp_pointer_construct (this, P, PN);} // requirements: D's copy constructor must not throw // shared_ptr will release P by calling d (P) // Template <class y, Class D> shared_ptr (y * P, d): Px (P), Pn (p, d) {boost: detail: sp_deleter_construct (this, p) ;}# if! Defined (boost_no_cxx11_nullptr) template <Class D> shared_ptr (boost: detail: sp_nullptr_t P, d): Px (P), Pn (p, d) {}# endif // as above, but with allocator. a's copy constructor shall not throw. template <class y, Class D, Class A> shared_ptr (y * P, d, a A): Px (P), Pn (p, D, a) {boost:: detail: sp_deleter_construct (this, p) ;}# if! Defined (boost_no_cxx11_nullptr) template <Class D, Class A> shared_ptr (boost: detail: sp_nullptr_t P, d, A): Px (P), Pn (p, d, a) {}# endif // generated copy constructor, destructor are fine... # If! Defined (boost_no_cxx11_rvalue_references )//... except t in C ++ 0x, move disables the implicit copy // copy constructor, two shared_ptr jointly manage a pointer shared_ptr (shared_ptr const & R) boost_no1_t: Px (R. px), Pn (R. PN) {}# endif template <class Y> explicit shared_ptr (weak_ptr <Y> const & R): PN (R. PN) // may throw {boost: detail: sp_assert_convertible <Y, T> (); // It is now safe to copy R. px, as Pn (R. PN) did no T throw PX = R. px;} template <class Y> shared_ptr (weak_ptr <Y> const & R, boost: detail: sp_nothrow_tag) boost_no1_t: Px (0), Pn (R. pn, boost: detail: sp_nothrow_tag () {If (! Pn. Empty () {PX = R. PX ;}} template <class y ># if! Defined (boost_sp_no_sp_convertible) shared_ptr (shared_ptr <Y> const & R, typename boost: detail: sp_enable_if_convertible <Y, t >:: type = boost :: detail :: sp_empty () # else shared_ptr (shared_ptr <Y> const & R) # endif boost_no1_t: Px (R. px), Pn (R. PN) {boost: detail: sp_assert_convertible <Y, T> ();} // aliasing template <class Y> shared_ptr (shared_ptr <Y> const & R, element_type * P) boost_n Oexcept: Px (P), Pn (R. PN) {}# ifndef boost_no_auto_ptr template <class Y> explicit shared_ptr (STD: auto_ptr <Y> & R): Px (R. get (), Pn () {boost: detail: sp_assert_convertible <Y, T> (); y * TMP = R. get (); Pn = boost: detail: shared_count (r); Boost: detail: sp_deleter_construct (this, TMP);} # If! Defined (boost_no_cxx11_rvalue_references) template <class Y> shared_ptr (STD: auto_ptr <Y> & R): Px (R. get (), Pn () {boost: detail: sp_assert_convertible <Y, T> (); y * TMP = R. get (); Pn = boost: detail: shared_count (r); Boost: detail: sp_deleter_construct (this, TMP);} # Elif! Defined (boost_no_sfinae )&&! Defined (partition) template <class AP> explicit shared_ptr (ap r, typename boost: detail: sp_enable_if_auto_ptr <AP, int >:: type = 0): Px (R. get (), Pn () {typedef typename AP: element_type y; Boost: detail: sp_assert_convertible <Y, T> (); y * TMP = R. get (); Pn = boost: detail: shared_count (r); Boost: detail: sp_deleter_construct (this, TMP);} # endif // boost_no _ Sfinae, boost_no_template_partial_specialization # endif // boost_no_auto_ptr # If! Defined (boost_no_cxx11_smart_ptr )&&! Defined (boost_no_cxx11_rvalue_references) template <class y, Class D> shared_ptr (STD: unique_ptr <Y, D> & R): Px (R. get (), Pn () {boost: detail: sp_assert_convertible <Y, T> (); typename STD: unique_ptr <Y, d> :: pointer TMP = R. get (); Pn = boost: detail: shared_count (r); Boost: detail: sp_deleter_construct (this, TMP );} # endif // assignment // overload value assignment operator shared_ptr & operator = (shared_ptr Co NST & R) boost_notest {this_type (R). Swap (* This); return * This ;}# if! Defined (boost_msvc) | (boost_msvc> = 1400) template <class Y> shared_ptr & operator = (shared_ptr <Y> const & R) boost_no1_t {this_type (R ). swap (* This); return * This;} # endif # ifndef boost_no_auto_ptr template <class Y> shared_ptr & operator = (STD: auto_ptr <Y> & R) {this_type (R ). swap (* This); return * This;} # If! Defined (boost_no_cxx11_rvalue_references) template <class Y> // & is a new feature of C ++ 11, indicating the right value reference (temporary object can be used) shared_ptr & operator = (STD :: auto_ptr <Y> & R) {this_type (static_cast <STD: auto_ptr <y >&> (r )). swap (* This); return * This;} # Elif! Defined (boost_no_sfinae )&&! Defined (partition) template <class AP> typename boost: detail: sp_enable_if_auto_ptr <AP, shared_ptr & >:: type operator = (ap r) {this_type (R ). swap (* This); return * This;} # endif // boost_no_sfinae, boost_no_template_partial_specialization # endif // boost_no_auto_ptr # If! Defined (boost_no_cxx11_smart_ptr )&&! Defined (boost_no_cxx11_rvalue_references) template <class y, Class D> shared_ptr & operator = (STD: unique_ptr <Y, D> & R) {this_type (static_cast <STD :: unique_ptr <Y, d >&&> (r )). swap (* This); return * This;} # endif // move support # If! Defined (boost_no_cxx11_rvalue_references) shared_ptr (shared_ptr & R) boost_no1_t: Px (R. px), Pn () {Pn. swap (R. PN); R. px = 0;} template <class Y> # If! Defined (boost_sp_no_sp_convertible) shared_ptr (shared_ptr <Y> & R, typename boost: detail: sp_enable_if_convertible <Y, t >:: type = boost :: detail :: sp_empty () # else shared_ptr (shared_ptr <Y> & R) # endif boost_no1_t: Px (R. px), Pn () {boost: detail: sp_assert_convertible <Y, T> (); Pn. swap (R. PN); R. px = 0;} shared_ptr & operator = (shared_ptr & R) boost_no1_t {this_type (static_cast <s Hared_ptr &> (r )). swap (* This); return * This;} template <class Y> shared_ptr & operator = (shared_ptr <Y> & R) boost_notest {this_type (static_cast <shared_ptr <y >&&> (r )). swap (* This); return * This;} # endif # If! Defined (boost_no_cxx11_nullptr) shared_ptr & operator = (boost: detail: sp_nullptr_t) boost_no1_t // never throws {this_type (). swap (* This); return * This;} # endif void reset () boost_notest // never throws in 1.30 + {// this_type () is a temporary object, after switching, * this becomes the default Original State this_type (). swap (* This);} template <class Y> void reset (y * P) // y must be complete {boost_assert (P = 0 | P! = Px); // catch self-Reset errors this_type (P ). swap (* This);} template <class y, Class D> void reset (y * P, d) {this_type (p, D ). swap (* This);} template <class y, Class D, Class A> void reset (y * P, d, a A) {this_type (p, D, a ). swap (* This);} template <class Y> void reset (shared_ptr <Y> const & R, element_type * P) {this_type (R, P ). swap (* This);} // never throws (but has a B Oost_assert in it, so not marked with boost_notest) // overload the dereference operator and return the object typename boost: detail: sp_dereference pointed to by the pointer <t >:: type operator *() const {boost_assert (PX! = 0); return * PX;} // never throws (but has a boost_assert in it, so not marked with boost_no1_t) // returns the original ecological pointer typename boost :: detail: sp_member_access <t >:: type operator-> () const {boost_assert (PX! = 0); Return PX;} // never throws (but has a boost_assert in it, so not marked with boost_no1_t) // It can also point to a pointer, the [] OPERATOR typename boost: detail: sp_array_access <t >:: type operator [] (STD: ptrdiff_t I) const {boost_assert (PX! = 0); boost_assert (I> = 0 & (I <boost: detail: sp_extent <t >:: value | boost: detail :: sp_extent <t >:: value = 0); Return PX [I] ;}// get the original ecological pointer element_type * Get () const boost_no1_t {return PX ;} // implicit conversion to "bool" # include <boost/smart_ptr/detail/operator_bool.hpp> // you can determine whether the pointer is the only bool unique () const boost_no1_t {return Pn. unique ();} // returns the number of pointer users to determine if the unique value is unique than use. _ Count () = 1 fast many long use_count () const boost_no1_t {return Pn. use_count ();} // swap/* STD: swap () source code is simple: Template <class T> void swap (T &, T & B) {t c (a); A = B; B = C;} */void swap (shared_ptr & Other) boost_no1_t {STD: swap (PX, other. px); Pn. swap (Other. PN);} template <class Y> bool owner_before (shared_ptr <Y> const & RHs) const boost_no1_t {return PN <RHS. PN;} template <Class y> bool owner_before (weak_ptr <Y> const & RHs) const boost_no1_t {return PN <RHS. PN;} void * _ internal_get_deleter (boost: detail: sp_typeinfo const & Ti) const boost_no1_t {return Pn. get_deleter (Ti);} void * _ internal_get_untyped_deleter () const boost_no1_t {return Pn. get_untyped_deleter ();} bool _ internal_equiv (shared_ptr const & R) const boost_no1_t {return PX = R. px & Pn = R. PN;} // tasteless as this may seem, making all members public allows member templates // to work in the absence of member template friends. (Matthew Langston) # ifndef Member: Template <class Y> friend class shared_ptr; Template <class Y> friend class weak_ptr; # endif // shared_ptr has only two data members, one pointer, the number of referenced pointers element_type * PX; // contained pointer boost: DETA Il: shared_count PN; // reference counter}; // shared_ptr // reload the equal sign and non-equal sign operator template <class t, class U> inline bool operator = (shared_ptr <t> const & A, shared_ptr <u> const & B) boost_no1_t {return. get () = B. get () ;}template <class T, Class U> inline bool Operator! = (Shared_ptr <t> const & A, shared_ptr <u> const & B) boost_no1_t {return a. Get ()! = B. Get () ;}# if _ gnuc _ = 2 & _ gnuc_minor _ <= 96 // resolve the ambiguity between our op! = And the one in rel_opstemplate <class T> inline bool Operator! = (Shared_ptr <t> const & A, shared_ptr <t> const & B) boost_no1_t {return a. Get ()! = B. Get () ;}# endif # If! Defined (boost_no_cxx11_nullptr) template <class T> inline bool operator = (shared_ptr <t> const & P, boost: detail: sp_nullptr_t) boost_no1_t {return p. get () = 0;} template <class T> inline bool operator = (boost: detail: sp_nullptr_t, shared_ptr <t> const & P) boost_no1_t {return p. get () = 0;} template <class T> inline bool Operator! = (Shared_ptr <t> const & P, boost: detail: sp_nullptr_t) boost_no1_t {return P. Get ()! = 0;} template <class T> inline bool Operator! = (Boost: detail: sp_nullptr_t, shared_ptr <t> const & P) boost_no1_t {return P. Get ()! = 0 ;}# endif // overload <comparison operator, which can be used to associate the Container set and maptemplate <class T, Class U> inline bool operator <(shared_ptr <t> const &, shared_ptr <u> const & B) boost_no1_t {return. owner_before (B);} template <class T> inline void swap (shared_ptr <t> & A, shared_ptr <t> & B) boost_no1_t {. swap (B);} // the pointer conversion is. Do not use static_cast and const_cast of C ++. This will cause the shared_ptr to fail to be managed. // use the following function for conversion, they also return shared_ptr <t> type template <class T, Class U> share D_ptr <t> static_pointer_cast (shared_ptr <u> const & R) boost_no1_t {(void) static_cast <t *> (static_cast <u *> (0 )); typedef typename shared_ptr <t>: element_type E; E * P = static_cast <E *> (R. get (); Return shared_ptr <t> (R, P);} template <class T, Class U> shared_ptr <t> const_pointer_cast (shared_ptr <u> const & R) boost_notest {(void) const_cast <t *> (static_cast <u *> (0); typede F typename shared_ptr <t>: element_type E; E * P = const_cast <E *> (R. get (); Return shared_ptr <t> (R, P);} template <class T, Class U> shared_ptr <t> dynamic_pointer_cast (shared_ptr <u> const & R) boost_nostmt {(void) dynamic_cast <t *> (static_cast <u *> (0); typedef typename shared_ptr <t>: element_type E; E * P = dynamic_cast <E *> (R. get (); Return P? Shared_ptr <t> (R, p): shared_ptr <t> ();} template <class T, Class U> shared_ptr <t> reinterpret_pointer_cast (shared_ptr <u> const & R) boost_nostmt {(void) reinterpret_cast <t *> (static_cast <u *> (0); typedef typename shared_ptr <t>: element_type E; E * P = reinterpret_cast <E *> (R. get (); Return shared_ptr <t> (R, P);} // get_pointer () enables boost: mem_fn to recognize shared_ptrtemplate <CL Ass T> inline typename shared_ptr <t>: element_type * get_pointer (shared_ptr <t> const & P) boost_now.t {return p. get () ;}// operator <# If! Defined (boost_no_iostream) # If defined (boost_no_templated_iostreams) | (defined (_ gnuc _) & (_ gnuc _ <3) template <class Y> STD:: ostream & operator <(STD: ostream & OS, shared_ptr <Y> const & P) {OS <p. get (); Return OS ;}# else // In stlport's no-iostreams mode No iostream symbols can be used # ifndef _ stlp_no_iostreams # If defined (boost_msvc) & boost_workaround (boost_msvc, <1300 & _ timeout) // msvc6 has problems finding STD: basic_ostream through the using declaration in namespace _ stlusing STD: basic_ostream; template <Class E, class T, class Y> basic_ostream <E, T> & operator <(basic_ostream <E, T> & OS, shared_ptr <Y> const & P) # elsetemplate <Class E, class T, class Y> STD: basic_ostream <E, T> & operator <(STD: basic_ostream <E, T> & OS, shared_ptr <Y> const & P) # endif {OS <p. get (); Return OS ;}


Boost source code learning --- shared_ptr.hpp

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.