boost智能指针之shared_ptr,scoped_ptr,intrusive_ptr,weak_ptr源码简析
boost库实现了各种智能指针,基本上都纳入了c++11标准中,boost库的smart_ptr目录下就是各种指针的实现了:
1.shared_ptr
template<class T> class shared_ptr
{
private:// Borland 5.5.1 specific workaroundtypedef 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{}#endiftemplate<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 copyshared_ptr( shared_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn ){}#endiftemplate<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 throwpx = 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() )#elseshared_ptr( shared_ptr<Y> const & r )#endifBOOST_NOEXCEPT : px( r.px ), pn( r.pn ){boost::detail::sp_assert_convertible< Y, T >();}// aliasingtemplate< class Y >shared_ptr( shared_ptr<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn ){}#ifndef BOOST_NO_AUTO_PTRtemplate<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// assignmentshared_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_PTRtemplate<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() )#elseshared_ptr( shared_ptr<Y> && r )#endifBOOST_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;}#endifvoid 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 errorsthis_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_FRIENDSprivate:template<class Y> friend class shared_ptr;template<class Y> friend class weak_ptr;#endifelement_type * px; // contained pointerboost::detail::shared_count pn; // reference counter}; // shared_ptr
可以看到里面的两个成员变量:
element_type * px; // contained pointer
boost::detail::shared_count pn; // reference counter
px用于保存原始指针,pn用于指针引用计数,构造函数和赋值运算符都是public,表示可以由shared_ptr构造、赋值,大部分情况下使用这个了,唯一缺点是两个类都用对方成员变量shared_ptr时,由于循环引用,使得引用计数无法减为0导致智能指针无法释放。
2.weak_ptr
template<class T> class weak_ptr
{
private:// Borland 5.5.1 specific workaroundstypedef 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 copyweak_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() )#elseweak_ptr( weak_ptr<Y> const & r )#endifBOOST_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() )#elseweak_ptr( weak_ptr<Y> && r )#endifBOOST_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 caseweak_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 caseweak_ptr & operator=( weak_ptr && r ) BOOST_NOEXCEPT{this_type( static_cast< weak_ptr && >( r ) ).swap( *this );return *this;}#endiftemplate<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() )#elseweak_ptr( shared_ptr<Y> const & r )#endifBOOST_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;}#endiftemplate<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;}#endifshared_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_FRIENDSprivate:template<class Y> friend class weak_ptr;template<class Y> friend class shared_ptr;#endifelement_type * px; // contained pointerboost::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_PTRexplicit 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 );
#endifboost::checked_delete( px );}void reset(T * p = 0) // never throws{BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errorsthis_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() )#elseintrusive_ptr( intrusive_ptr<U> const & rhs )#endif: px( rhs.get() ){if( px != 0 ) intrusive_ptr_add_ref( px );}#endifintrusive_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;}#endifintrusive_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智能指针之shared_ptr,scoped_ptr,intrusive_ptr,weak_ptr源码简析相关推荐
- 在你的代码中使用Boost智能指针
在你的代码中使用Boost智能指针 Smart Pointers to boost your code(By peterchen) 翻译 masterlee Download source file ...
- 【C++11新特性】 C++11智能指针之shared_ptr
http://blog.csdn.net/Xiejingfa/article/details/50750037 原创作品,转载请标明:http://blog.csdn.net/Xiejingfa/ar ...
- C++ 智能指针std::shared_ptr简单使用和理解
参考:https://blog.csdn.net/u011068702/article/details/83692838 1 智能指针std::shared_ptr相关知识和如何使用 我们这里先说下 ...
- C++11 智能指针之shared_ptr
0.Overview 在实际的 C++ 开发中,我们经常会遇到诸如程序运行中突然崩溃.程序运行所用内存越来越多最终不得不重启等问题,这些问题往往都是内存资源管理不当造成的.比如: 有些内存资源已经被释 ...
- 智能指针之shared_ptr易错点05
一 shared_ptr易错点 1 慎用裸指针给shared_ptr赋值 例1 class A {public:A() {};A(int i) {m_i=i;cout<<"A&q ...
- 【C++11智能指针】shared_ptr的初始化、拷贝构造和拷贝赋值、移动构造和移动赋值
文章目录 1.智能指针概述 2.shared_ptr的初始化 2.1 shared_ptr和new结合使用(直接初始化) 2.2 make_shared函数 3.shared_ptr的拷贝构造和拷贝赋 ...
- C++之智能指针std::shared_ptr简单使用和理解
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程 1 智能指针std::shared_ptr相关知识和如何使用 我们这里先说下智能指针std::sha ...
- C++ 实现智能指针:shared_ptr 和 unique_ptr
简 述: C++11 智能指针的深入分析,和动手实现简版的智能指针 std::shared_ptr .std::unique_ptr 文章目录 背景 std::shared_ptr 原理 代码 ref ...
- c语言 ptr 用法,C++之智能指针std::shared_ptr简单使用和理解
1 智能指针std::shared_ptr相关知识和如何使用 我们这里先说下智能指针std::shared_ptr,因为我看到我我们项目c++代码里面用得很多,我不是不会,所以记录学习下 先让ubu ...
最新文章
- spoj453 Sums in a Triangle (tutorial) 动态规划
- 期末不挂科のJAVA
- sqlserver中文显示问号_解决 SecureCRT 和 SecureFX 中文乱码
- 常见的js算法面试题收集,es6实现
- Educational Codeforces Round 33 (Rated for Div. 2) E. Counting Arrays
- python列表、字典、元组的用法及区别_python列表,字典,元组简单用法示例
- java poi 导出excel 速度慢_java POI技术之导出数据优化(15万条数据1分多钟)
- Activity的传递数据与实例
- 前端导出Excel兼容写法
- CAS在Tomcat中实现单点登录
- 常用的linux命令-vim
- 计算机在高分子材料与工程中的应用,计算机技术在高分子材料工程中的应用.doc...
- 灰鸽子病毒——网络神偷之后应用最广的反弹端口***
- 手机怎样和宽带连接无线路由器设置路由器连接服务器,手机设置路由器步骤_用手机怎么设置路由器?-192路由网...
- H3C运维审计系统 故障处理手册(笔记)
- 公章,加盖公章,英语怎么说?
- 适用于iOS的远程桌面软件
- Chrome 浏览器 Cookie 跨域共享与升级问题
- linux备份磁盘数据,linux下vmstat输出数据分析-linux下dd命令备份磁盘的节点(...-linux watch命令用法简介(图文)_169IT.COM...
- 仓库码放要求_库房货品堆码管理规定,货品码放层数、高度、间距标准
热门文章
- 怎么把json数据转化为数组_RESTful API 返回统一JSON数据格式是怎么实现的?
- Spring学习5之自动装配Bean01
- nbiot开发需要掌握什么_包装设计需要掌握什么技巧
- 【java8中的时间操作】java8中获取月的最后一天或者总天数,JDK8 LocalDate AP
- 学生信息的添加与查询_JAVA
- 【数据结构与算法】2.深度优先搜索DFS、广度优先搜索BFS
- Java 垃圾回收机制概念梳理
- 键空间通知(keyspace notification)
- Spring - Java/J2EE Application Framework 应用框架 第 4 章 属性编辑器,数据绑定,校验与BeanWeapper(Bean封装)
- Javadoc注释规范