I've been watching it recently Boost Library source code ,Boost Powerful library , But its source code is too much , It takes too much time to read carefully , After all, there is something else to learn , So I decided to skim over the chapters of interest , Write down the design ideas and the incomprehensible .

shared_ptr yes Boost The most valuable intelligent pointer in it . It encapsulates a primitive pointer and a reference counter , This reference counter is a class shared_count.shared_ptr Support comparison operation , It's overloaded operator<, Therefore, it can be used for set and map.

In conversion shared_ptr Pointer time , use ***_pointer_cast Defined function to convert ( return shared_ptr<T> type ), If used static_cast,reinterpret_cast And so on shared_ptr Pointers cannot be managed properly .

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 several constructors below , In order to adapt to the needs of different situations
// Default constructor ,px Is a pointer ,pn Is a counter ( It is a class shared_count, Its default constructor sets its value to 0) shared_ptr()
BOOST_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+ { } #if !defined(
BOOST_NO_CXX11_NULLPTR ) shared_ptr( boost::detail::sp_nullptr_t )
BOOST_NOEXCEPT : px( 0 ), pn() // never throws { } #endif // use Y Type to initialize ,Y Possibility and possibility T It's a different type
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 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 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 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 d, A a ): px( p ), pn( p, d, a ) { } #endif //
generated copy constructor, destructor are fine... #if !defined(
BOOST_NO_CXX11_RVALUE_REFERENCES ) // ... except in C++0x, move disables the
implicit copy // copy constructor , Two shared_ptr Manage one pointer together shared_ptr( shared_ptr const & r )
BOOST_NOEXCEPT : 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 not throw px = r.px; } template<class Y> shared_ptr(
weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ) BOOST_NOEXCEPT : 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_NOEXCEPT : 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_NOEXCEPT : 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(
BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) 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 assignment operator shared_ptr & operator=( shared_ptr const & r ) BOOST_NOEXCEPT {
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_NOEXCEPT { 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>
//&& yes C++11 New features of , Represents an R-value reference ( Temporary objects 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(
BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) 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_NOEXCEPT : 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_NOEXCEPT : 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_NOEXCEPT { this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
return *this; } template<class Y> shared_ptr & operator=( shared_ptr<Y> && r )
BOOST_NOEXCEPT { 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_NOEXCEPT // never throws {
this_type().swap(*this); return *this; } #endif void reset() BOOST_NOEXCEPT //
never throws in 1.30+ { //this_type() Is a temporary object , After exchange *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
d ) { this_type( p, d ).swap( *this ); } template<class Y, class D, class A>
void reset( Y * p, D 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 BOOST_ASSERT in
it, so not marked with BOOST_NOEXCEPT) // Overload dereference operator , Returns the object pointed to by the pointer typename
boost::detail::sp_dereference< T >::type operator* () const { BOOST_ASSERT( px
!= 0 ); return *px; } // never throws (but has a BOOST_ASSERT in it, so not
marked with BOOST_NOEXCEPT) // Overloaded arrow operator , Return to 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_NOEXCEPT) // It can also point to a pointer , It's overloaded [] 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 We can get the original ecological indicator element_type * get() const
BOOST_NOEXCEPT { return px; } // implicit conversion to "bool" #include
<boost/smart_ptr/detail/operator_bool.hpp> // You can determine whether the pointer user is unique bool unique()
const BOOST_NOEXCEPT { return pn.unique(); }
// Returns the number of pointer users , Judging whether it is the only one unique than use_count()==1 Much faster long use_count() const
BOOST_NOEXCEPT { return pn.use_count(); } // So many of the above copy constructors are used swap /*
std::swap() The source code is very simple : template <class T> void swap ( T& a, T& b ) { T c(a); a=b;
b=c; } */ void swap( shared_ptr & other ) BOOST_NOEXCEPT { std::swap(px,
other.px); pn.swap(other.pn); } template<class Y> bool owner_before(
shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT { return pn < rhs.pn; }
template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const
BOOST_NOEXCEPT { return pn < rhs.pn; } void * _internal_get_deleter(
boost::detail::sp_typeinfo const & ti ) const BOOST_NOEXCEPT { return
pn.get_deleter( ti ); } void * _internal_get_untyped_deleter() const
BOOST_NOEXCEPT { return pn.get_untyped_deleter(); } bool _internal_equiv(
shared_ptr const & r ) const BOOST_NOEXCEPT { 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 BOOST_NO_MEMBER_TEMPLATE_FRIENDS private: template<class Y>
friend class shared_ptr; template<class Y> friend class weak_ptr; #endif
//shared_ptr Only two data members , A pointer , The number of a reference pointer element_type * px; // contained pointer
boost::detail::shared_count pn; // reference counter }; // shared_ptr
// Overloading the equal and unequal operators template<class T, class U> inline bool operator==(shared_ptr<T>
const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT { return a.get() == b.get();
} template<class T, class U> inline bool operator!=(shared_ptr<T> const & a,
shared_ptr<U> const & b) BOOST_NOEXCEPT { return a.get() != b.get(); } #if
__GNUC__ == 2 && __GNUC_MINOR__ <= 96 // Resolve the ambiguity between our op!=
and the one in rel_ops template<class T> inline bool operator!=(shared_ptr<T>
const & a, shared_ptr<T> const & b) BOOST_NOEXCEPT { 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_NOEXCEPT { return p.get() == 0; } template<class T> inline bool
operator==( boost::detail::sp_nullptr_t, shared_ptr<T> const & p )
BOOST_NOEXCEPT { return p.get() == 0; } template<class T> inline bool
operator!=( shared_ptr<T> const & p, boost::detail::sp_nullptr_t )
BOOST_NOEXCEPT { return p.get() != 0; } template<class T> inline bool
operator!=( boost::detail::sp_nullptr_t, shared_ptr<T> const & p )
BOOST_NOEXCEPT { return p.get() != 0; } #endif // heavy load < Comparison operator , Can be used to associate containers set and map
template<class T, class U> inline bool operator<(shared_ptr<T> const & a,
shared_ptr<U> const & b) BOOST_NOEXCEPT { return a.owner_before( b ); }
template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
BOOST_NOEXCEPT { a.swap(b); }
// Pointer conversion is , Don't use it C++ Of static_cast,const_cast, This will create shared_ptr Unable to manage
// Use the following function to convert , They also returned shared_ptr<T> type template<class T, class U> shared_ptr<T>
static_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT { (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_NOEXCEPT { (void)
const_cast< T* >( static_cast< U* >( 0 ) ); typedef 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_NOEXCEPT { (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_NOEXCEPT { (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_ptr template<class T> inline typename
shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p)
BOOST_NOEXCEPT { 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 && __SGI_STL_PORT) // MSVC6 has problems
finding std::basic_ostream through the using declaration in namespace _STL
using 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) # else
template<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; }

Technology
©2019-2020 Toolsou All rights reserved,
SQL Server Database Glossary CSS Animation effect dedecms Website is hacked How to solve hijacking to other websites Count the number of letters (java Language implementation )Java Basics ( Three ) String In depth analysis The difference between static method and non static method And storage location Django Personal blog building tutorial --- Time classified archiving Keras Save and load model (JSON+HDF5)hive Summary of processing methods for a large number of small files Website mobile phone number capture method