boost智能指针之shared_ptr,scoped_ptr,intrusive_ptr,weak_ptr源码简析
2017-10-22 00:53
645 查看
boost库实现了各种智能指针,基本上都纳入了c++11标准中,boost库的smart_ptr目录下就是各种指针的实现了:
1.shared_ptr
可以看到里面的两个成员变量:
2.weak_ptr
与shared_ptr不同的是引用计数的类型为weak_count,在detail里面的表示引用计数使用detail里面的弱引用实现,表示通过shared_ptr构造时不修改引用计数,适用循环引用的情况,一般作为shared_ptr出现循环引用的情况补充。
3.scoped_ptr
与上面不同的是,只有一个成员保存原始指针的成员px,表明它不支持引用计数:
拷贝构造和赋值都是private,说明禁止指针复制和拷贝构造
4.intrusive_ptr
依然只有保存原始指针的成员变量,没有引用计数的成员变量,不过里面出现了两个类中没有定义的函数:
智能指针的几个参考资料
http://www.cnblogs.com/sld666666/archive/2010/12/16/1908265.html http://blog.csdn.net/callmeback/article/details/7729251 http://blog.csdn.net/yockie/article/details/8840205 http://blog.csdn.net/lanxuezaipiao/article/details/41603883 http://blog.csdn.net/e5max/article/details/50569305 http://blog.csdn.net/lollipop_jin/article/details/8499530 http://blog.csdn.net/liufei_learning/article/details/34808549 http://blog.csdn.net/lwbeyond/article/details/6202256/
1.shared_ptr
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; 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 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 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 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> 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().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) 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) 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) 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 ]; } element_type * get() const BOOST_NOEXCEPT { return px; } // implicit conversion to "bool" #include <boost/smart_ptr/detail/operator_bool.hpp> bool unique() const BOOST_NOEXCEPT { return pn.unique(); } long use_count() const BOOST_NOEXCEPT { return pn.use_count(); } 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 element_type * px; // contained pointer boost::detail::shared_count pn; // reference counter }; // shared_ptr
可以看到里面的两个成员变量:
element_type * px; // contained pointer boost::detail::shared_count pn; // reference counterpx用于保存原始指针,pn用于指针引用计数,构造函数和赋值运算符都是public,表示可以由shared_ptr构造、赋值,大部分情况下使用这个了,唯一缺点是两个类都用对方成员变量shared_ptr时,由于循环引用,使得引用计数无法减为0导致智能指针无法释放。
2.weak_ptr
template<class T> class weak_ptr { private: // Borland 5.5.1 specific workarounds typedef weak_ptr<T> this_type; public: typedef typename boost::detail::sp_element< T >::type element_type; weak_ptr() BOOST_NOEXCEPT : px(0), pn() // never throws in 1.30+ { } // generated copy constructor, assignment, destructor are fine... #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // ... except in C++0x, move disables the implicit copy weak_ptr( weak_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) { } weak_ptr & operator=( weak_ptr const & r ) BOOST_NOEXCEPT { px = r.px; pn = r.pn; return *this; } #endif // // The "obvious" converting constructor implementation: // // template<class Y> // weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws // { // } // // has a serious problem. // // r.px may already have been invalidated. The px(r.px) // conversion may require access to *r.px (virtual inheritance). // // It is not possible to avoid spurious access violations since // in multithreaded programs r.px may be invalidated at any point. // template<class Y> #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) weak_ptr( weak_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() ) #else weak_ptr( weak_ptr<Y> const & r ) #endif BOOST_NOEXCEPT : px(r.lock().get()), pn(r.pn) { boost::detail::sp_assert_convertible< Y, T >(); } #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) template<class Y> #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) weak_ptr( weak_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() ) #else weak_ptr( weak_ptr<Y> && r ) #endif BOOST_NOEXCEPT : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) { boost::detail::sp_assert_convertible< Y, T >(); r.px = 0; } // for better efficiency in the T == Y case weak_ptr( weak_ptr && r ) BOOST_NOEXCEPT : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) { r.px = 0; } // for better efficiency in the T == Y case weak_ptr & operator=( weak_ptr && r ) BOOST_NOEXCEPT { this_type( static_cast< weak_ptr && >( r ) ).swap( *this ); return *this; } #endif template<class Y> #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) weak_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() ) #else weak_ptr( shared_ptr<Y> const & r ) #endif BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) { boost::detail::sp_assert_convertible< Y, T >(); } #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300) template<class Y> weak_ptr & operator=( weak_ptr<Y> const & r ) BOOST_NOEXCEPT { boost::detail::sp_assert_convertible< Y, T >(); px = r.lock().get(); pn = r.pn; return *this; } #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) template<class Y> weak_ptr & operator=( weak_ptr<Y> && r ) BOOST_NOEXCEPT { this_type( static_cast< weak_ptr<Y> && >( r ) ).swap( *this ); return *this; } #endif template<class Y> weak_ptr & operator=( shared_ptr<Y> const & r ) BOOST_NOEXCEPT { boost::detail::sp_assert_convertible< Y, T >(); px = r.px; pn = r.pn; return *this; } #endif shared_ptr<T> lock() const BOOST_NOEXCEPT { return shared_ptr<T>( *this, boost::detail::sp_nothrow_tag() ); } long use_count() const BOOST_NOEXCEPT { return pn.use_count(); } bool expired() const BOOST_NOEXCEPT { return pn.use_count() == 0; } bool _empty() const // extension, not in std::weak_ptr { return pn.empty(); } void reset() BOOST_NOEXCEPT // never throws in 1.30+ { this_type().swap(*this); } void swap(this_type & other) BOOST_NOEXCEPT { std::swap(px, other.px); pn.swap(other.pn); } template<typename Y> void _internal_aliasing_assign(weak_ptr<Y> const & r, element_type * px2) { px = px2; pn = r.pn; } template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT { return pn < rhs.pn; } template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT { return pn < rhs.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 weak_ptr; template<class Y> friend class shared_ptr; #endif element_type * px; // contained pointer boost::detail::weak_count pn; // reference counter }; // weak_ptr还是2个成员变量:
template<class Y> friend class weak_ptr; template<class Y> friend class shared_ptr;
与shared_ptr不同的是引用计数的类型为weak_count,在detail里面的表示引用计数使用detail里面的弱引用实现,表示通过shared_ptr构造时不修改引用计数,适用循环引用的情况,一般作为shared_ptr出现循环引用的情况补充。
3.scoped_ptr
template<class T> class scoped_ptr // noncopyable { private: T * px; scoped_ptr(scoped_ptr const &); scoped_ptr & operator=(scoped_ptr const &); typedef scoped_ptr<T> this_type; void operator==( scoped_ptr const& ) const; void operator!=( scoped_ptr const& ) const; public: typedef T element_type; explicit scoped_ptr( T * p = 0 ): px( p ) // never throws { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) boost::sp_scalar_constructor_hook( px ); #endif } #ifndef BOOST_NO_AUTO_PTR explicit scoped_ptr( std::auto_ptr<T> p ) BOOST_NOEXCEPT : px( p.release() ) { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) boost::sp_scalar_constructor_hook( px ); #endif } #endif ~scoped_ptr() // never throws { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) boost::sp_scalar_destructor_hook( px ); #endif boost::checked_delete( px ); } void reset(T * p = 0) // never throws { BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors this_type(p).swap(*this); } T & operator*() const // never throws { BOOST_ASSERT( px != 0 ); return *px; } T * operator->() const // never throws { BOOST_ASSERT( px != 0 ); return px; } T * get() const BOOST_NOEXCEPT { return px; } // implicit conversion to "bool" #include <boost/smart_ptr/detail/operator_bool.hpp> void swap(scoped_ptr & b) BOOST_NOEXCEPT { T * tmp = b.px; b.px = px; px = tmp; } };
与上面不同的是,只有一个成员保存原始指针的成员px,表明它不支持引用计数:
T * px;
拷贝构造和赋值都是private,说明禁止指针复制和拷贝构造
private: T * px; scoped_ptr(scoped_ptr const &); scoped_ptr & operator=(scoped_ptr const &); typedef scoped_ptr<T> this_type; void operator==( scoped_ptr const& ) const; void operator!=( scoped_ptr const& ) const;
4.intrusive_ptr
template<class T> class intrusive_ptr { private: typedef intrusive_ptr this_type; public: typedef T element_type; intrusive_ptr() BOOST_NOEXCEPT : px( 0 ) { } intrusive_ptr( T * p, bool add_ref = true ): px( p ) { if( px != 0 && add_ref ) intrusive_ptr_add_ref( px ); } #if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) template<class U> #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) intrusive_ptr( intrusive_ptr<U> const & rhs, typename boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty() ) #else intrusive_ptr( intrusive_ptr<U> const & rhs ) #endif : px( rhs.get() ) { if( px != 0 ) intrusive_ptr_add_ref( px ); } #endif intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px ) { if( px != 0 ) intrusive_ptr_add_ref( px ); } ~intrusive_ptr() { if( px != 0 ) intrusive_ptr_release( px ); } #if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs) { this_type(rhs).swap(*this); return *this; } #endif // Move support #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) intrusive_ptr(intrusive_ptr && rhs) BOOST_NOEXCEPT : px( rhs.px ) { rhs.px = 0; } intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_NOEXCEPT { this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this); return *this; } #endif intrusive_ptr & operator=(intrusive_ptr const & rhs) { this_type(rhs).swap(*this); return *this; } intrusive_ptr & operator=(T * rhs) { this_type(rhs).swap(*this); return *this; } void reset() BOOST_NOEXCEPT { this_type().swap( *this ); } void reset( T * rhs ) { this_type( rhs ).swap( *this ); } T * get() const BOOST_NOEXCEPT { return px; } T & operator*() const { BOOST_ASSERT( px != 0 ); return *px; } T * operator->() const { BOOST_ASSERT( px != 0 ); return px; } // implicit conversion to "bool" #include <boost/smart_ptr/detail/operator_bool.hpp> void swap(intrusive_ptr & rhs) BOOST_NOEXCEPT { T * tmp = px; px = rhs.px; rhs.px = tmp; } private: T * px; };
依然只有保存原始指针的成员变量,没有引用计数的成员变量,不过里面出现了两个类中没有定义的函数:
intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px ) { if( px != 0 ) intrusive_ptr_add_ref( px ); } ~intrusive_ptr() { if( px != 0 ) intrusive_ptr_release( px ); }intrusive_ptr_add_ref( T * )和intrusive_ptr_release(T * )都作用于用户原始指针,用户要在两个函数中实现引用计数以及指针的销毁,找了一下网上作为友元函数的实现:
friend void intrusive_ptr_add_ref(intrusive_ptr_base<T> const* s) { // 下面代码只是为了演示 std::cout << " intrusive_ptr_add_ref... " << std::endl; // 判断合法性并自增 assert(s != 0); assert(s->ref_count >= 0); ++s->ref_count; } // 递增引用计数 // 用友元函数的方式来实现,避免了函数指针类型的转换 // 例如: // template<typename T> void intrusive_ptr_release(T* t) // { // T->release(); // 此处需要定义T的原型 // } friend void intrusive_ptr_release(intrusive_ptr_base<T> const* s) { // 下面代码只是为了演示 std::cout << " intrusive_ptr_release... " << std::endl; // 判断合法性并自减 assert(s != 0); assert(s->ref_count >= 0); if (--s->ref_count == 0) { // 进行静态类型检查,防止出错 boost::checked_delete(static_cast<T const*>(s)); } }
智能指针的几个参考资料
http://www.cnblogs.com/sld666666/archive/2010/12/16/1908265.html http://blog.csdn.net/callmeback/article/details/7729251 http://blog.csdn.net/yockie/article/details/8840205 http://blog.csdn.net/lanxuezaipiao/article/details/41603883 http://blog.csdn.net/e5max/article/details/50569305 http://blog.csdn.net/lollipop_jin/article/details/8499530 http://blog.csdn.net/liufei_learning/article/details/34808549 http://blog.csdn.net/lwbeyond/article/details/6202256/
相关文章推荐
- Boost智能指针:scoped_ptr shared_ptr weak_ptr
- 详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)
- [置顶] 从零开始学C++之boost库(一):详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)
- 从零开始学C++之boost库(一):详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)
- Boost智能指针——scoped_ptr、shared_ptr、weak_ptr、intrusive_ptr
- 详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)
- [置顶] 从零开始学C++之boost库(一):详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)
- auto_ptr、shared_ptr、weak_ptr、scoped_ptr用法小结
- boost智能指针之shared_ptr和weak_ptr
- 智能指针shared_ptr, auto_ptr, scoped_ptr, weak_ptr总结
- 浅析Boost智能指针:scoped_ptr shared_ptr weak_ptr
- auto_ptr、shared_ptr、weak_ptr、scoped_ptr用法小结
- 浅析Boost智能指针:scoped_ptr shared_ptr weak_ptr
- 智能指针——AutoPtr & ScopedPer & SharedPtr & WeakPtr
- C++智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> )
- boost::shared_ptr 和 boost::weak_ptr 和 scoped_ptr
- shared_ptr&scoped_ptr&weak_ptr
- auto_ptr、shared_ptr、weak_ptr、scoped_ptr用法小结
- auto_ptr、shared_ptr、weak_ptr、scoped_ptr用法小结
- Boost库学习随记三 smart_ptr库、soped_ptr、scoped_array、shared_ptr、shared_array、weak_ptr等等