刚开始因为不明白为什么use_count为0后weak_ptr还可以取得use_count, 所以看了一下shared_ptr和weak_ptr的代码, 这里把关键的代码都提取出来了,方便大家阅读
//sp_counted_base class sp_counted_base { private: // 不可复制 sp_counted_base( sp_counted_base const &); sp_counted_base & operator= ( sp_counted_base const &); // 两个成员, 只有弱计数到0了才会销毁对象 long use_count_; // 用于shared_ptr long weak_count_; // 用于weak_ptr public: sp_counted_base() : use_count_( 1 ), weak_count_( 1 ) { // 两个成员初始化为1 } virtual ~sp_counted_base() { } virtual void dispose() = 0; // 用于子类销毁自有的东西 virtual void destroy() { delete this; } void add_ref_copy() { BOOST_INTERLOCKED_INCREMENT( &use_count ); // 用于shared_ptr的复制赋值, 因为有shared_ptr就不怕对象被销毁 // 不用像下一个函数那么复杂 // BOOST_INTERLOCKED_INCREMENT 保证了原子操作 } void add_ref_lock() { for ( ;; ) //最高效的死循环 { long tmp = static_cast< long const volatile & >( use_count_ ); if ( tmp == 0 ) return false; if ( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true; // 这里 保证了在for的一次循环中, &use_count_的值没有被改变过的情况下把_usr_count递增1 // BOOST_INTERLOCKED_COMPARE_EXCHANGE的意思是 // use_count的值和 tmp相等时, use_count=tmp+1 // 返回的大概是use_count原来的值, 这个我还没查 } } void release() { if ( BOOST_INTERLOCKED_DECREMENT( &use_count_ ) == 0 ) { dispose(); // 指向的对象是删除了, 但sp_counted_base对象还要看下面情况 weak_release(); //use_count_为0了还要看weak_count_ } } void weak_add_ref() { BOOST_INTERLOCKED_INCREMENT( &weak_count_ ); // 用于weak_ptr } void weak_release() { if ( BOOST_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 ) { destroy(); } } long use_count() const { // 确保最新最准的 return static_cast<long const volatile &>( use_count_ ); } }; // sp_counted_base 一个子类 template<class X> class sp_counted_impl_p: public sp_counted_base { private: X * px_; //存放指针处 // 不可复制 sp_counted_impl_p( sp_counted_impl_p const & ); sp_counted_impl_p & operator= ( sp_counted_impl_p const & ); typedef sp_counted_impl_p<X> this_type; public: explicit sp_counted_impl_p( X * px ): px_( px ) { //基类两个成员就默认设为1了 } virtual void dispose() { boost::checked_delete( px_ ); } }; // shared_count // weak_count class weak_count; class shared_count { private: sp_counted_base * pi_; friend class weak_count; public: shared_count(): pi_(0) { } template<class Y> explicit shared_count( Y * p) { try { pi_ = new sp_counted_impl_p<Y>( p ); } catch(...) { boost::checked_delete( p ); //当Y不是完整类型时编译会出错,具体请百度 throw } } ~shared_count() { if ( pi_ != 0 ) pi_->release(); } shared_count(shared_count const & r): pi_(r.pi_) { if( pi_ != 0 ) pi_->add_ref_copy(); } shared_count(shared_count && r): pi_(r.pi) //C++新特性, 还没查资料, 先站位 { r.pi_ = 0; } //因为weak_count还没定义 //所以这个函数后面才定义 shared_count(weak_count const & r, sp_nothrow_tag); shared_count & operator= (shared_count const & r) { sp_counted_base * tmp = r.pi_; if (tmp != pi_ ) { if (tmp != 0 ) tmp->add_ref_copy(); if (pi_ != 0 ) pi_->release(); return this; } } void swap(shared_count & r) { sp_counted_base * tmp = r.pi_; r.pi_ = pi_; pi_ = tmp; } long use_count() const { return pi_ != 0 ? pi_->use_count() : 0; } bool unique() const { return use_count() == 1; } bool empty() const { return pi_ == 0; } }; class weak_count { private: sp_counted_base * pi_; friend class shared_count; public: weak_count(): pi_(0) { } weak_count()(shared_count const & r ): pi_(r.pi_) { if(pi_ != 0) pi_->weak_add_ref(); } weak_count()(weak_count const & r ): pi_(r.pi_) { if(pi_ != 0) pi_->weak_add_ref(); } ~weak_count() { if(pi_ != 0) pi_->weak_release(); //开始时只增加了weak_count_所以析构时只减少weak_count_ } weak_count & operator= (shared_count const & r) { sp_counted_base * tmp = r.pi_; if( tmp != pi_ ) { if(tmp != 0) tmp->weak_add_ref(); if(pi_ != 0) pi_->weak_release(); pi_ = tmp; } return *this; } void swap(weak_count & r) { sp_counted_base * tmp = r.pi_; r.pi_ = pi_; pi_ = tmp; } long use_count() const { return pi_ != 0? pi_->use_count(): 0; } bool empty() const { return pi_ == 0; } }; inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag): pi_( r.pi_ ) { if( pi_ != 0 && !pi_->add_ref_lock() ) { pi_ = 0; } } template<class T> class weak_ptr { // 不用析构函数的, 默认的析构函数够用了 private: typedef weak_ptr<T> this_type; T *px; weak_count pn; //不是指针 public: weak_ptr(): px(0), pn() { } template<class Y> weak_ptr( weak_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() ) : px(r.lock().get()), pn(r.pn) { //如果用:px(r.px),pn(r.pn)在多线程下不安全 //sp_enable_if_convertible的代码请找源码 } template<class Y> weak_ptr( shared_ptr<Y> const r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() ) :px(r.px), pn(r.pn) { } template<class Y> weak_ptr & operator=(weak_ptr<Y> const & r) { px = r.lock().get(); //这里编译期保证了是否能够转换 pn = r.pn; } template<class Y> weak_ptr & operator=(shared_ptr<Y> const & r) { px = r.px; pn = r.pn; return *this; } shared_ptr<T> lock() const { return shared_ptr<this_type>( *this, boost::detail::sp_nothrow_tag() ); } long use_count() const { return pn.use_count(); } bool expired() const { return pn.use_count() == 0; } void reset() { this_type().swap(*this); } void swap(this_type & other) { std::swap(px, other.px); pn.swap(other.pn); } }; template<class T> class shared_ptr { // 不用析构函数的, 默认的析构函数够用了 private: typedef shared_ptr<T> this_type; T * px; shared_count pn; public: shared_ptr(): px(0), pn() { } template<class Y> explicit shared_ptr( Y* p): px( p ), pn( p ) { //还没弄懂这句 boost::detail::sp_enable_shared_from_this( this, p, p ); } template<class Y> shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) { if( !pn.empty() ) { px = r.px; } } template<class Y> shared_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() ) : px( r.px ), pn( r.pn ) { } shared_ptr & operator=( shared_ptr const & r ) { this_type(r).swap(*this); return *this; } template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r) { this_type(r).swap(*this);// this_type(r)保证了Y和T能够转换 return *this; } void reset() { this_type().swap(*this); } template<class Y> void reset(Y * p) { BOOST_ASSERT(p == 0 || p != px); //保证不用自己的指针重设 this_type(p).swap(*this); } // 如果T是 void const, void volatile, void const volatile会有不同, // 具体请看源码 T & opterator* () const { BOOST_ASSERT(px != 0); return *px; } T * opterator-> () const { BOOST_ASSERT(px != 0); //vc上等于assert(px != 0), 其它编译器没看 return px; } T * get() const { return px; } ////////////////////////////这里插入了一段unspecified_bool_type的东西 //用于隐式转换成bool #include <boost/smart_ptr/detail/operator_bool.hpp> //////////////////////////// bool unique() const { //书中说use_count效率比unique低, 但从代码中看不是这样 return pn.unique(); } long use_count() const { return pn.use_count(); } void swap(shared_ptr<T> & other) { std::swap(px, other.px); pn.swap(other.pn); } };
原文链接: https://www.cnblogs.com/one-piece/archive/2011/09/28/2194890.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/33257
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!