精华内容
下载资源
问答
  • C++智能指针:weak_ptr实现详解

    千次阅读 2019-08-07 00:53:51
    weak_ptr描述 声明 头文件:<memory> 模版类:template <class T> class weak_ptr 声明方式:std::weak_ptr<type_id> statement 作用 根据boost库的官方描述,weak_ptr是由shared_ptr管理的一种弱...

    weak_ptr描述

    声明

    头文件:<memory>
    模版类:template <class T> class weak_ptr
    声明方式:std::weak_ptr<type_id> statement

    作用

    根据boost库的官方描述,weak_ptr是由shared_ptr管理的一种弱引用对象的模版类。weak_ptr的对象能够使用shared_ptr指针的构造函数转换为一个shared_ptr对象。但是这里shared_ptr的构造函数参数需要包含weak_ptr的lock成员,该成员是weak_ptr用来获取shared_ptr的指针。

    这样当shared_ptr在多线程过程中被销毁时shared_ptr::reset,weak_ptr的lock成员仍然能够保留shared_ptr的成员,直到当前shared_ptr正常终止,否则会出现非常危险的内存泄漏。关于lock()成员的作用如下描述:
    如下代码

    shared_ptr<int> p(new int(5));
    weak_ptr<int> q(p);
    
    // some time later
    
    if(int * r = q.get()) 
    {
        // use *r
    }
    

    多线程环境中shared_ptr是可以被多个线程共享,在r被使用之前p对象执行了p.reset(),正如我们上一篇文章中对shared_ptr的描述(C++智能指针:shared_ptr 实现详解),reset成员会重置当前shared_ptr指针的指向。此时,当前线程如果继续使用r指针,势必会产生访问空地址的异常问题

    根据以上问题,使用weak_ptr::lock()成员来解决该问题

    shared_ptr<int> p(new int(5));
    weak_ptr<int> q(p);
    
    // some time later
    
    //使用weak_ptr的lock成员来获取shared_ptr的指针
    if(shared_ptr<int> r = q.lock())
    {
        // use *r
    }
    

    关于lock()成员简单说明一下,lock成员获取到的shared_ptr p指针创建一个临时对象(我们weak_ptr弱引用的体现),这个临时对象同样指向p,即使p执了reset这样的delete引用的操作,弱引用对象仍然持有改智能指针的地址,直到r指针的生命周期结束才会释放。不得不佩服C++语言设计者的脑洞,为了保持C++对内存操作的自由,即使耗费再大的精力也要实现这一目标,工匠精神才让今天的C++越来越被底层程序员喜欢。

    原理实现

    源码文件/boost/smart_ptr/weak_ptr.hpp

    template<class T> class weak_ptr
    {
    private:
    
        // Borland 5.5.1 specific workarounds
        typedef weak_ptr<T> this_type;
    
    • constructor 构造函数
      //默认构造函数
      weak_ptr() BOOST_NOEXCEPT : px(0), pn() // never throws in 1.30+
      {
      }
      
      //拷贝构造函数
      weak_ptr( weak_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
      {
      }
      
    • destructor析构函数,这里weak_ptr使用的是默认析构函数,一般使用expired返回空对象或者user_count()为0的情况则辅助shared_ptr释放引用
    • operator=
      1. 
       weak_ptr & operator=( weak_ptr && r ) BOOST_NOEXCEPT
      {
          this_type( static_cast< weak_ptr && >( r ) ).swap( *this );
          return *this;
      }
      
      //2.这里会更加安全,使用lock成员获取Y类型的指针
      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;
      }
      
      3.
      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;
      }
      
    • weak_ptr::swap成员,交换两个weak_ptr所指内容以及地址
       void swap(this_type & other) BOOST_NOEXCEPT
      {
      	//先交换地址,再交换内容
          std::swap(px, other.px);
          pn.swap(other.pn);
      }
      
    • weak_ptr::reset成员,·重新指定对象地址和内容,就像是重新使用默认构造函数进行了初始化
      void reset() BOOST_NOEXCEPT // never throws in 1.30+
      {
      	//使用默认构造函数构造的对象和当前对象进行swap操作
          this_type().swap(*this);
      }
      
    • weak_ptr::use_count成员,获取shared_ptr对象被引用的次数。如果为空,则返回0
      long use_count() const BOOST_NOEXCEPT
      {
          return pn.use_count();
      }
      
    • weak_ptr::expired成员,当根据use_count==0来返回bool,其返回为true的时候,使用lock获取weak_ptr的指针只能获取到空指针
       bool expired() const BOOST_NOEXCEPT
      {
          return pn.use_count() == 0;
      }
      
    • weak_ptr::lock成员,会向weak_ptr对象返回一个shared_ptr。正如我们之前在weak_ptr作用中所描述的,防止多线程访问时的shared_ptr内存泄漏。此时weak_ptr对象获取到的指针为临时指针,会指向shared_ptr对象之前所指向的地址。
      shared_ptr<T> lock() const BOOST_NOEXCEPT
      {
          return shared_ptr<T>( *this, boost::detail::sp_nothrow_tag() );
      }
      

    函数成员使用

    • 构造函数
      #include <iostream>
      #include <memory>
      
      struct C {int* data;};
      
      int main () {
        std::shared_ptr<int> sp (new int);
      
        std::weak_ptr<int> wp1;
        std::weak_ptr<int> wp2 (wp1);
        std::weak_ptr<int> wp3 (sp);
      
        std::cout << "use_count:\n";
        
        //weak_ptr对象如果为经shared_ptr初始化,
        //它是没有引用计数的,所以这里wp1和wp2引用计数都为0
        //只有wp3经过了shared_ptr初始化,它的引用计数才为1
        
        std::cout << "wp1: " << wp1.use_count() << '\n';
        std::cout << "wp2: " << wp2.use_count() << '\n';
        std::cout << "wp3: " << wp3.use_count() << '\n';
        
        return 0;
      }
      
      输出如下:
      use_count:
      wp1: 0
      wp2: 0
      wp3: 1
      
    • weak_ptr::operator=赋值运算符
      // weak_ptr::operator= example
      #include <iostream>
      #include <memory>
      
      int main () {
        std::shared_ptr<int> sp1,sp2;
        std::weak_ptr<int> wp;
                                             // sharing group:
                                             // --------------
        sp1 = std::make_shared<int> (10);    // sp1
        wp = sp1;                            // sp1, wp
      
        sp2 = wp.lock();                     // sp1, wp, sp2
        sp1.reset();                         //      wp, sp2
      
        //通过lock保留的临时指针,重新获取到了shared_ptr共享的地址
        sp1 = wp.lock();                     // sp1, wp, sp2
      
        std::cout << "*sp1: " << *sp1 << '\n';
        std::cout << "*sp2: " << *sp2 << '\n';
      
        return 0;
      }
      
      输出如下
      *sp1: 10
      *sp2: 10
      
    • std::weak_ptr::swap交换指针地址以及对应的内容
      #include <iostream>
      #include <memory>
      
      int main () {
        std::shared_ptr<int> sp1 (new int(10));
        std::shared_ptr<int> sp2 (new int(20));
      
        std::weak_ptr<int> wp1(sp1);
        std::weak_ptr<int> wp2(sp2);
        
        std::cout << "wp1 -> " << *wp1.lock() << " " << wp1.lock() << '\n';
        std::cout << "wp2 -> " << *wp2.lock() << " " << wp2.lock() << '\n';
      
        //这里的swap仅仅是交换wp2的各自的指向地址
        //并不会直接导致对应智能指针原始指针的地址交换
        //根据输出,所以很明显,交换完成之后weak_ptr对象指向发生了变化,但是并未导致share_ptr指针的指向变化
        wp1.swap(wp2);
      
        std::cout << "sp1 -> " << *sp1 << " " << sp1 << '\n';
        std::cout << "sp2 -> " << *sp2 << " " << sp2 << '\n';
        std::cout << "wp1 -> " << *wp1.lock() << " " << wp1.lock() << '\n';
        std::cout << "wp2 -> " << *wp2.lock() << " " << wp2.lock() << '\n';
      
        return 0;
      }
      
      输出如下:
      wp1 -> 10 0x11daf90
      wp2 -> 20 0x11dafd0
      sp1 -> 10 0x11daf90
      sp2 -> 20 0x11dafd0
      wp1 -> 20 0x11dafd0
      wp2 -> 10 0x11daf90
      
    • std::weak_ptr::reset成员,执行之后weak_ptr对象就像是重新执行了默认构造函数,又变成了一个空的对象
      // weak_ptr::reset example
      #include <iostream>
      #include <memory>
      
      int main () {
        std::shared_ptr<int> sp (new int(10));
      
        std::weak_ptr<int> wp(sp);
      
        std::cout << "1. wp " << (wp.expired()?"is":"is not") << " expired\n";
        std::cout << "4. wp " << wp.use_count() << " *wp " << *wp.lock() << '\n';
      
        wp.reset();
      
        std::cout << "2. wp " << (wp.expired()?"is":"is not") << " expired\n";
        std::cout << "3. sp " << sp.use_count() << " *sp " << *sp << '\n';
      
        return 0;
      }
      
      输出如下
      1. wp is not expired
      2. wp 2 *wp 10
      3. wp is expired
      4. sp 1 *sp 10
      

    总结

    shared_ptr和weak_ptr主要区别如下

    1. shared_ptr对象能够初始化实际指向一个地址内容而weak_ptr对象没办法直接初始化一个具体地址,它的对象需要由shared_ptr去初始化
    2. weak_ptr不会影响shared_ptr的引用计数,因为它是一个弱引用,只是一个临时引用指向shared_ptr。即使用shared_ptr对象初始化weak_ptr不会导致shared_ptr引用计数增加。依此特性可以解决shared_ptr的循环引用问题。
    3. weak_ptr没有解引用*和获取指针->运算符,它只能通过lock成员函数去获取对应的shared_ptr智能指针对象,从而获取对应的地址和内容。

    参考文档:
    http://www.cplusplus.com/reference/memory/weak_ptr/
    https://www.boost.org/doc/libs/1_66_0/libs/smart_ptr/doc/html/smart_ptr.html#weak_ptr

    展开全文
  • #ifndef __SHARED_PTR_ #define __SHARED_PTR_ template <typename T> class shared_ptr { public: shared_ptr(T* p) : count(new int(1)), _ptr(p) {} shared_ptr(shared_ptr<T>& other) : ...
    #ifndef __SHARED_PTR_
    #define __SHARED_PTR_
    
    template <typename T>
    class shared_ptr {
    public:
        shared_ptr(T* p) : count(new int(1)), _ptr(p) {}
        shared_ptr(shared_ptr<T>& other) : count(&(++*other.count)), _ptr(other._ptr) {}
        T* operator->() { return _ptr; }
        T& operator*() { return *_ptr; }
        shared_ptr<T>& operator=(shared_ptr<T>& other)
        {
            if(this == &other) return *this;
            ++*other.count;
            if (this->_ptr && 0 == --*this->count)
            {
                delete count;
                delete _ptr;
            }
            this->_ptr = other._ptr;
            this->count = other.count;
            return *this;
        }
        ~shared_ptr()
        {
            if (--*count == 0)
            {
                delete count;
                delete _ptr;
            }
        }
        int getRef() { return *count; }
    private:
        int* count;
        T* _ptr;
    };
    
    
    #endif

    shared_ptr的使用是创建一个局部shared_ptr对象。利用对象的自释放减少计数,一般在两个地方:

    1,过了作用域。

    2,作为另一个对象中的变量,另一个对象自动销毁的时候,也算作用域结束了。

     

    class CB;
    class CA
    {
    public:
        CA() { cout << "CA() called! " << endl; }
        ~CA() { cout << "~CA() called! " << endl; }
        void set_ptr(shared_ptr<CB>& ptr) { m_ptr_b = ptr; }
        void b_use_count() { cout << "b use count : " << m_ptr_b.use_count() << endl; }
        void show() { cout << "this is class CA!" << endl; }
    private:
        shared_ptr<CB> m_ptr_b;
    };
    
    class CB
    {
    public:
        CB() { cout << "CB() called! " << endl; }
        ~CB() { cout << "~CB() called! " << endl; }
        void set_ptr(shared_ptr<CA>& ptr) { m_ptr_a = ptr; }
        void a_use_count() { cout << "a use count : " << m_ptr_a.use_count() << endl; }
        void show() { cout << "this is class CB!" << endl; }
    private:
        shared_ptr<CA> m_ptr_a;
    };
    
    void test_refer_to_each_other()
    {
        shared_ptr<CA> ptr_a(new CA());
        shared_ptr<CB> ptr_b(new CB());
    
        cout << "a use count : " << ptr_a.use_count() << endl;//1
        cout << "b use count : " << ptr_b.use_count() << endl;//1
    
        ptr_a->set_ptr(ptr_b);
        ptr_b->set_ptr(ptr_a);
    
        cout << "a use count : " << ptr_a.use_count() << endl;//2
        cout << "b use count : " << ptr_b.use_count() << endl;//2
        //这里局部变量ptr_a结束作用域,引用次数-1,还剩1,无法释放
    }
    

    使用weak_ptr

    class CB
    {
    public:
        CB() { cout << "CB() called! " << endl; }
        ~CB() { cout << "~CB() called! " << endl; }
        void set_ptr(shared_ptr<CA>& ptr) { m_ptr_a = ptr; }// 这里没有增加ptr的引用计数
        void a_use_count() { cout << "a use count : " << m_ptr_a.use_count() << endl; }
        void show() { cout << "this is class CB!" << endl; }
    private:
        weak_ptr<CA> m_ptr_a;
    };
    

    结束的时候,ptr_b的引用计数从2减到1,没释放。

    ptr_a的引用计数从1减到0,释放new出来的CA,

    CA中的m_ptr_b也被释放,计数从1到0,于是也被释放。

    于是都被释放了。

     

    // 20200806weakptr.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    // weak_ptr::operator= example
    #include <iostream>
    #include <memory>
    
    int main() {
    	std::shared_ptr<int> sp1, sp2;
    	std::weak_ptr<int> wp;
    	// sharing group:
    	// --------------
    	sp1 = std::make_shared<int>(10);    // sp1
    	wp = sp1;                            // sp1, wp
    	std::cout << "sp1 use count" << sp1.use_count() << std::endl; // 1
    
    	sp2 = wp.lock();                     // sp1, wp, sp2
    	std::cout << "sp1 use count" << sp1.use_count() << std::endl;// 2
    	std::cout << "sp2 use count" << sp2.use_count() << std::endl;// 2
    
    	sp1.reset();                         //      wp, sp2
    	std::cout << "sp1 use count" << sp1.use_count() << std::endl;// 0, 0 after reset
    	std::cout << "sp2 use count" << sp2.use_count() << std::endl;// 1
    
    	//通过lock保留的临时指针,重新获取到了shared_ptr共享的地址
    	sp1 = wp.lock();                     // sp1, wp, sp2
    	std::cout << "sp1 use count" << sp1.use_count() << std::endl;// 2
    	std::cout << "sp2 use count" << sp2.use_count() << std::endl;// 2
    
    	std::cout << "*sp1: " << *sp1 << '\n';
    	std::cout << "*sp2: " << *sp2 << '\n';
    
    	if (!wp.expired())
    	{
    		std::cout << "sp1 use count" << sp1.use_count() << std::endl;// 2
    		std::cout << "sp2 use count" << sp2.use_count() << std::endl;// 2
    		std::cout << "sp lock use count" << wp.lock().use_count() << std::endl;// 3 // 用完就会再释放掉
    	}
    
    	if (std::shared_ptr<int> sp3 = wp.lock())
    	{
    		std::cout << "sp1 use count" << sp1.use_count() << std::endl;// 3
    		std::cout << "sp2 use count" << sp2.use_count() << std::endl;// 3
    		std::cout << "sp3 use count" << sp3.use_count() << std::endl;// 3
    	}
    
    	std::cout << "sp1 use count" << sp1.use_count() << std::endl;// 2
    	std::cout << "sp2 use count" << sp2.use_count() << std::endl;// 2
    
    	return 0;
    }
    
    

    别人的实现:

    template <class S>
    friend class shared_ptr;
    
    constexpr weak_ptr() noexcept : m_iWeakRefCount(nullptr), m_ptr(nullptr) { }
    
    weak_ptr( const weak_ptr<T>& rhs ) noexcept : m_iWeakRefCount(rhs.m_iWeakRefCount)
    {
        m_ptr = rhs.lock().getPointer();
    }
    
    weak_ptr( const shared_ptr<T>& rhs ) noexcept
     : m_iWeakRefCount(rhs.m_iRefCount), m_ptr(rhs.m_ptr) { }
    
    template <typename S>
    weak_ptr & operator=(const shared_ptr<S> & rhs)
    {
        m_ptr = dynamic_cast<T *>(rhs.m_ptr);
        m_iWeakRefCount = rhs.m_iRefCount;
        return *this;
    }
    
    template <typename S>
    weak_ptr & operator=(const weak_ptr<S> & rhs)
    {
        m_ptr = dynamic_cast<T *>(rhs.m_ptr);
        m_iWeakRefCount = rhs.m_iWeakRefCount;
        return *this;
    }
    
    weak_ptr& operator=( const weak_ptr& rhs ) noexcept
    {
        m_iWeakRefCount = rhs.m_iWeakRefCount;
        m_ptr = rhs.m_ptr;
    
        return *this;
    }
    
    weak_ptr& operator=( const shared_ptr<T>& rhs ) noexcept
    {
        m_iWeakRefCount = rhs.m_iRefCount;
        m_ptr = rhs.m_ptr;
    
        return *this;
    }
    
    shared_ptr<T> lock() const noexcept
    {
        shared_ptr<T> tmp;
        if(m_iWeakRefCount && *m_iWeakRefCount > 0)
        {
            tmp.m_iRefCount = m_iWeakRefCount;
            tmp.m_ptr = m_ptr;
    
            if(tmp.m_iRefCount)
            {
                ++(*tmp.m_iRefCount);
            }
        }
    
        return tmp;
    }
    
    int use_count()
    {
        return *m_iWeakRefCount;
    }
    
    bool expired() const noexcept
    { 
        return *m_iWeakRefCount == 0;
    }
    
    void Reset()
    {
        m_ptr = NULL;
        m_iWeakRefCount = NULL;
    }

     

    展开全文
  • c++最开始设计没有考虑gc(garbage collection...shared_ptr原理是引用计数,用于指针需要被传递复制的时候 weak_ptr主要就是为了配合shared_ptr防止出现循环引用(两个对象各持有各自的shared_ptr, 都无法先释放), ...

    前言

    c++最开始设计没有考虑gc(garbage collection)机制,后续c++11推出后STL标准库中增加了三个智能指针类,合理运用下可以让c++程序员摆脱忘记delete或者free的困扰
    shared_ptr原理是引用计数,用于指针需要被传递复制的时候
    weak_ptr主要就是为了配合shared_ptr防止出现循环引用(两个对象各持有各自的shared_ptr, 都无法先释放)
    unique_ptr不可复制,离开作用域自动销毁,但是可以移动拷贝


    一、语法使用

    1.1 shared_ptr语法

    // 测试类
    class Test {
    public:
    	void test() {
    	}
    };
    
    /* shared_ptr语法 */
    // 1.初始化方式
    std::shared_ptr<Test> sp(new Test()); // 正确,构造函数初始化
    
    std::shared_ptr<Test> sp1 = std::make_shared<Test>(); // 正确,make_shared初始化
    
    std::share_ptr<Test> sp2; 
    sp2.reset(new Test()); // 正确,reset初始化
    
    std::shared_ptr<Test> sp3 = new Test(); // 错误, shared_ptr是一个类,构造的sp是一个对象,不可以直接用指针赋值
    									  // 除非重载赋值运算符=特殊处理,但是shared_ptr没有重载=
    
    // 2.其他操作
    Test sp1 = *sp; // 重载*运算符 获取原始指针实际值
    sp->test(); //  重载->运算符 调用保存的原始指针成员函数
    Test *sp2 = sp.get(); // 获取原始指针
    if (sp) {} // 重载bool()函数,判断指针是否为空
    

    1.2 weak_ptr语法

    /* weak_ptr语法 */
    // 1.初始化方式
    std::shared_ptr<Test> sp(new Test());
    std::weak_ptr<Test> sp_weak(sp); // 通过shared_ptr构造
    std::weak_ptr<Test> sp_weak1 = sp;	// 通过shared_ptr赋值构造
    std::weak_ptr<Test> sp_weak2(sp_weak); // 通过weak_ptr构造
    
    // 2.其他操作
    std::shared_ptr<Test> sp3 = sp_weak.lock(); // weak_ptr不能直接操作原始指针,需要的话需调用lock升级为shared_ptr
    if (sp_weak.expired()) {} // 判断绑定的shared_ptr是否已析构
    

    1.3 unique_ptr语法

    /* unique_ptr语法 */
    // 1.初始化方式
    std::unique_ptr<Test> up(new Test()); // 构造函数初始化
    
    std::unique_ptr<Test> up1 = std::make_unique<Test>(); // c11暂不支持,c17以后支持
    
    std::unique_ptr<Test> up2; 
    up2.reset(new Test()); // reset初始化
    
    //2.其他操作
    
    // 2.其他操作
    Test up1 = *up; // 重载*运算符 获取原始指针实际值
    up->test(); //  重载->运算符 调用保存的原始指针成员函数
    Test *up2 = up.get(); // 获取原始指针
    if (up) {} // 重载bool()函数,判断指针是否为空
    

    1.4 三指针的区别
    shared_ptr 和 unique_ptr在语法上没有区别,唯一的区别的是shared_ptr支持赋值共享,unique_ptr不允许赋值(原理是禁用赋值构造)但是可以引用传递
    weak_ptr是专门用来解决shared_ptr循环引用的问题的,本身不能操作原始指针

    二、shared_ptr代码实现

    1.1 shared_ptr实现

    #include <iostream>
    using namespace std;
    
    template <class T>
    class shared_ptr {
    private:
        // 保存真实指针
        T* ptr_;
        // 指向引用计数
        int* ref_count_; 
    
    public:
        shared_ptr(T *t) {
            ptr_ = t;
            // 初始化引用计数
            if (ref_count_ == NULL) {
                ref_count_ = new int(1);
            }
        }
    
        shared_ptr(shared_ptr& ptr) {
            ptr_ = ptr->ptr_;
            // 引用计数加1
            ref_count_ = ptr->ref_count_;
            (*ref_count_)++;
        }
    
        void operator =(shared_ptr& ptr) {
            ptr_ = ptr->ptr_;
            // 引用计数加1
            ref_count_ = ptr->ref_count_;
            (*ref_count_)++;
        }
        
    	T* get() {
    		return ptr_;
    	}
    
        T operator *() {
            return *ptr_;
        }
    
        T* operator ->() {
            return ptr_;
        } 
    };
    
    class A {
    public:
        A() {}
        int test() {
            return 1;
        }
    };
    
    int main () {
        shared_ptr<A> sp(new A);
        cout << sp->test() << endl;
        return 0;
    }
    

    shared_ptr使用注意事项

    • 尽量不要使用get()获取原始指针,防止其他删除原指针造成double free
    • 如果类要返回this指针,最好使类继承enable_shared_from_this,然后 return shared_from_this();
    展开全文
  • C++智能指针 shared_ptrweak_ptr 原理

    千次阅读 2017-12-12 15:46:56
    注:源代码摘自 GNU C++,除此之外为原创,转载请注明出处。 ...// // This file is part of the GNU ISO C++ Library. 一、weak_ptr 的 lock() 函数原理/* 当每次有新的 shared_ptr 生成时,会增加 _Sp_
    • 注:源代码摘自 GNU C++,除此之外为原创,转载请注明出处。

    欢迎关注 [懒人漫说] 公众号,分享Java、Android、C/C++ 技术,
    包括基础、自己遇到的问题解决过程。
    在这里插入图片描述
    当然如果关注并留言问题的话,我们力所能及的话会帮你解决并回复哟。我们和你一样,是正在成长的程序员,我们也会分享自己的成长路上的感想,希望可以和你一起努力成长。

    // Copyright (C) 2007-2016 Free Software Foundation, Inc.
    //
    // This file is part of the GNU ISO C++ Library. 
    

    一、weak_ptr 的 lock() 函数原理

    /*  当每次有新的 shared_ptr 生成时,会增加 _Sp_counted_base 的 _M_use_count (+1);
    	当每次有新的 weak_ptr 生成时,会增加 _Sp_counted_base 的 _M_weak_count (+1);
    	通过weak_ptr<x>::lock()函数可以获取x对象的强引用(shared_ptr)。
    	对应的,shared_ptr 析构时,会调用 _Sp_counted_base 的 _M_release 来使 _M_use_count (-1);
    	weak_ptr 析构时,会调用 _Sp_counted_base 的 _M_release 来使 _M_weak_count (-1);
    	当 _M_use_count 的数量为 0 的时候 就会释放,原始的对象(用户自定义对象) 的内存,但是不会释放 
    	_Sp_counted_base 的内存。
    	当  _M_use_count 和 _M_weak_count 都为 0的时候, 才会释放 _Sp_counted_base 的内存。
    	所以将一个普通指针赋值给两个不同的shared_ptr对象会引发double free。
    	eg: 
    		int *n = new int(2);
    		shared_ptr<int> pn1(n);
    		shared_ptr<int> pn2(n);
    		// pn1 和 pn2 内部保存的指针都是n,而且内部引用计数都为1,所以在离开作用域的时候两个指针都会发生析构并释放指向的内存n。
    		尽量使用 shared_ptr<int> pn = make_shared<int> (2); 这种形式初始化一个shared_ptr指针。
    	*/
    /*
     *    此处引用 《Linux 多线程 服务端编程 使用 muduo C++ 网络库》 中对这两个智能指针的描述:
     *      1 shared_ptr 控制对象的生命期。shared_ptr 是强引用,只要有一个指向x对象的shared_ptr存在,该x对象就不会
     *   析构。当指向对象x的最后一个shared_ptr析构或reset()的时候,x保证会被销毁。
     *      2 weak_ptr 不控制对象的生命期,但是它知道对象是否还活着。如果对象还活着,那么它可以提升(promote)为有效的
     *   shared_ptr; 如果对象已经死了,提升会失败,返回一个空的shared_ptr。“提升/lock()” 行为是线程安全的。
     *      3 shared_ptr/weak_ptr 的“计数”在主流平台上是原子操作,没有用锁,性能不俗。
     *      4 shared_ptr/weak_ptr 的线程安全级别与 std::string和STL容器一样。
    */
    	
    	// __shared_count的构造函数会 new 一个 计数对象(_Sp_counted_base),但是__weak_count的构造函数不会new。
    	__shared_count(_Ptr __p) : _M_pi(0)
    	{
    		__try {
    			typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp;
    			_M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>(
    				__p, _Sp_deleter<_Tp>());
    				
    		} __catch(...) {
    			delete __p;
    			__throw_exception_again;
    		}
    	}
    
    	// lock 函数
    	__shared_ptr<_Tp, _Lp> lock() const // never throws
    		{
    	#ifdef __GTHREADS
    			// Optimization: avoid throw overhead.
    			if (expired())
    				return __shared_ptr<element_type, _lp = "">();
    	
    			__try {
    				return __shared_ptr<element_type, _lp = "">(*this);
    				
    			} __catch(const bad_weak_ptr&) {
    				return __shared_ptr<element_type, _lp = "">();
    			}
    	
    	#else
    			// Optimization: avoid try/catch overhead when single threaded.
    			return expired() ? __shared_ptr<element_type, _lp = "">()
    				: __shared_ptr<element_type, _lp = "">(*this);
    	
    	#endif
    		} // XXX MT
    	
    	bool  expired() const // never throws
    	{
    			return _M_refcount._M_get_use_count() == 0;
    	}
    

    二、类成员图:
    这里写图片描述

    三、下面源码有点长,不差资源分的话可以点击链接下载。
    *注:所有的源码参看连接: http://download.csdn.net/download/u013005025/10155393

    四、源码 (//version: Copyright © 2007-2016 Free Software Foundation, Inc.)

    1 weak_ptr 源码
    
    // weak_ptr
    template<typename _tp = "">
    class weak_ptr
    	: public __weak_ptr < _Tp >
    {
    public:
    	weak_ptr()
    		: __weak_ptr<_Tp>() { }
    
    	template<typename _tp1 = "">
    	weak_ptr(const weak_ptr<_Tp1>& __r)
    		: __weak_ptr<_Tp>(__r) { }
    
    	template<typename _tp1 = "">
    	weak_ptr(const shared_ptr<_Tp1>& __r)
    		: __weak_ptr<_Tp>(__r) { }
    
    	template<typename _tp1 = "">
    	weak_ptr&
    		operator=(const weak_ptr<_Tp1>& __r) // never throws
    	{
    		this->__weak_ptr<_Tp>::operator=(__r);
    		return *this;
    	}
    
    	template<typename _tp1 = "">
    	weak_ptr& operator=(const shared_ptr<_Tp1>& __r) // never throws
    	{
    		this->__weak_ptr<_Tp>::operator=(__r);
    		return *this;
    	}
    
    	shared_ptr<_Tp>	lock() const // never throws
    	{
    #ifdef __GTHREADS
    		if (this->expired())
    			return shared_ptr<_Tp>();
    
    		__try{
    			return shared_ptr<_Tp>(*this);
    			
    		}__catch(const bad_weak_ptr&){
    			return shared_ptr<_Tp>();
    		}
    #else
    		return this->expired() ? shared_ptr<_Tp>()
    			: shared_ptr<_Tp>(*this);
    #endif
    	}
    };
    
    2  __weak_ptr 源码
    
    template<typename _lock_policy = "" _lp = "">
    class __weak_ptr
    {
    public:
    	typedef _Tp element_type;
    
    	__weak_ptr() : _M_ptr(0), _M_refcount() // never throws
    	{ }
    	
    	template<typename _tp1 = "">
    	__weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
    		: _M_refcount(__r._M_refcount) // never throws
    	{
    		__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    			_M_ptr = __r.lock().get();
    	}
    
    	template<typename _tp1 = "">
    	__weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
    		: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
    	{
    		__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    	}
    
    	template<typename _tp1 = "">
    	__weak_ptr& operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
    	{
    		_M_ptr = __r.lock().get();
    		_M_refcount = __r._M_refcount;
    		return *this;
    	}
    
    	template<typename _tp1 = "">
    	__weak_ptr& operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
    	{
    		_M_ptr = __r._M_ptr;
    		_M_refcount = __r._M_refcount;
    		return *this;
    	}
    
    	__shared_ptr<_Tp, _Lp> lock() const // never throws
    	{
    #ifdef __GTHREADS
    		// Optimization: avoid throw overhead.
    		if (expired())
    			return __shared_ptr<element_type, _lp = "">();
    
    		__try {
    			return __shared_ptr<element_type, _lp = "">(*this);
    			
    		} __catch(const bad_weak_ptr&) {
    			return __shared_ptr<element_type, _lp = "">();
    		}
    
    #else
    		// Optimization: avoid try/catch overhead when single threaded.
    		return expired() ? __shared_ptr<element_type, _lp = "">()
    			: __shared_ptr<element_type, _lp = "">(*this);
    
    #endif
    	} // XXX MT
    
    	long use_count() const // never throws
    	{
    		return _M_refcount._M_get_use_count();
    	}
    
    	bool expired() const // never throws
    	{
    		return _M_refcount._M_get_use_count() == 0;
    	}
    
    	void reset() // never throws
    	{
    		__weak_ptr().swap(*this);
    	}
    
    	void swap(__weak_ptr& __s) // never throws
    	{
    		std::swap(_M_ptr, __s._M_ptr);
    		_M_refcount._M_swap(__s._M_refcount);
    	}
    
    private:
    	// Used by __enable_shared_from_this.
    	void _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
    	{
    		_M_ptr = __ptr;
    		_M_refcount = __refcount;
    	}
    
    	template<typename _tp1 = "">
    	bool _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
    	{
    		return _M_refcount < __rhs._M_refcount;
    	}
    
    	template<typename _lock_policy = "" _lp1 = ""> friend class __shared_ptr;
    	template<typename _lock_policy = "" _lp1 = ""> friend class __weak_ptr;
    	friend class __enable_shared_from_this < _Tp, _Lp > ;
    	friend class enable_shared_from_this < _Tp > ;
    
    	// Friend injected into namespace and found by ADL.
    	template<typename _tp1 = "">
    	friend inline bool
    		operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
    	{
    		return __lhs._M_less(__rhs);
    	}
    
    	_Tp*           _M_ptr;         // Contained pointer.
    	__weak_count<_Lp>  _M_refcount;    // Reference counter.
    };
    
    3 __weak_count 源码
    
    template<_Lock_policy _Lp>
    class __weak_count
    {
    public:
    	__weak_count() : _M_pi(0) // nothrow
    	{ }
    
    	__weak_count(const __shared_count<_Lp>& __r)
    		: _M_pi(__r._M_pi) // nothrow
    	{
    		if (_M_pi != 0)
    			_M_pi->_M_weak_add_ref();
    	}
    
    	__weak_count(const __weak_count<_Lp>& __r)
    		: _M_pi(__r._M_pi) // nothrow
    	{
    		if (_M_pi != 0)
    			_M_pi->_M_weak_add_ref();
    	}
    
    	~__weak_count() // nothrow
    	{
    		if (_M_pi != 0)
    			_M_pi->_M_weak_release();
    	}
    
    	__weak_count<_Lp>& operator=(const __shared_count<_Lp>& __r) // nothrow
    	{
    		_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    		if (__tmp != 0)
    			__tmp->_M_weak_add_ref();
    		if (_M_pi != 0)
    			_M_pi->_M_weak_release();
    		_M_pi = __tmp;
    		return *this;
    	}
    
    	__weak_count<_Lp>& operator=(const __weak_count<_Lp>& __r) // nothrow
    	{
    		_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    		if (__tmp != 0)
    			__tmp->_M_weak_add_ref();
    		if (_M_pi != 0)
    			_M_pi->_M_weak_release();
    		_M_pi = __tmp;
    		return *this;
    	}
    
    	void _M_swap(__weak_count<_Lp>& __r) // nothrow
    	{
    		_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    		__r._M_pi = _M_pi;
    		_M_pi = __tmp;
    	}
    
    	long _M_get_use_count() const // nothrow
    	{
    		return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0;
    	}
    
    	friend inline bool
    		operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
    	{
    		return __a._M_pi == __b._M_pi;
    	}
    
    	friend inline bool
    		operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
    	{
    		return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi);
    	}
    
    private:
    	friend class __shared_count < _Lp > ;
    
    	_Sp_counted_base<_Lp>*  _M_pi;
    };
    

    五、shared_ptr 源码

    // The actual shared_ptr, with forwarding constructors and
    // assignment operators.
    // shared_ptr
    template<typename _tp = "">
    class shared_ptr
    	: public __shared_ptr < _Tp >
    {
    public:
    	shared_ptr()
    		: __shared_ptr<_Tp>() { }
    
    	template<typename _tp1 = "">
    	explicit
    		shared_ptr(_Tp1* __p)
    		: __shared_ptr<_Tp>(__p) { }
    
    	template<typename _deleter = "" typename = "">
    	shared_ptr(_Tp1* __p, _Deleter __d)
    		: __shared_ptr<_Tp>(__p, __d) { }
    
    	template<typename _tp1 = "">
    	shared_ptr(const shared_ptr<_Tp1>& __r)
    		: __shared_ptr<_Tp>(__r) { }
    
    	template<typename _tp1 = "">
    	explicit
    		shared_ptr(const weak_ptr<_Tp1>& __r)
    		: __shared_ptr<_Tp>(__r) { }
    
    #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
    	template<typename _tp1 = "">
    	explicit
    		shared_ptr(std::auto_ptr<_Tp1>& __r)
    		: __shared_ptr<_Tp>(__r) { }
    #endif
    
    	template<typename _tp1 = "">
    	shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
    		: __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
    
    	template<typename _tp1 = "">
    	shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
    		: __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
    
    	template<typename _tp1 = "">
    	shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
    		: __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
    
    	template<typename _tp1 = "">
    	shared_ptr& operator=(const shared_ptr<_Tp1>& __r) // never throws
    	{
    		this->__shared_ptr<_Tp>::operator=(__r);
    		return *this;
    	}
    
    #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
    	template<typename _tp1 = "">
    	shared_ptr& operator=(std::auto_ptr<_Tp1>& __r)
    	{
    		this->__shared_ptr<_Tp>::operator=(__r);
    		return *this;
    	}
    #endif
    };
    
    // __shared_ptr
    struct __static_cast_tag { };
    struct __const_cast_tag { };
    struct __dynamic_cast_tag { };
    // A smart pointer with reference-counted copy semantics.  The
    // object pointed to is deleted when the last shared_ptr pointing to
    // it is destroyed or reset.
    template<typename _lock_policy = "" _lp = "">
    class __shared_ptr
    {
    public:
    	typedef _Tp   element_type;
    
    	__shared_ptr()
    		: _M_ptr(0), _M_refcount() // never throws
    	{ }
    
    	template<typename _tp1 = "">
    	explicit __shared_ptr(_Tp1* __p)
    		: _M_ptr(__p), _M_refcount(__p)
    	{
    		__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    			typedef int _IsComplete[sizeof(_Tp1)];
    		__enable_shared_from_this_helper(_M_refcount, __p, __p);
    	}
    
    	template<typename _deleter = "" typename = "">
    	__shared_ptr(_Tp1* __p, _Deleter __d)
    		: _M_ptr(__p), _M_refcount(__p, __d)
    	{
    		__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    			// TODO requires _Deleter CopyConstructible and __d(__p) well-formed
    			__enable_shared_from_this_helper(_M_refcount, __p, __p);
    	}
    
    	//  generated copy constructor, assignment, destructor are fine.
    
    	template<typename _tp1 = "">
    	__shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
    		: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
    	{
    		__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    	}
    
    	template<typename _tp1 = "">
    	explicit
    		__shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
    		: _M_refcount(__r._M_refcount) // may throw
    	{
    		__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    			// It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
    			// did not throw.
    			_M_ptr = __r._M_ptr;
    	}
    
    #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
    	// Postcondition: use_count() == 1 and __r.get() == 0
    	template<typename _tp1 = "">
    	explicit __shared_ptr(std::auto_ptr<_Tp1>& __r)
    		: _M_ptr(__r.get()), _M_refcount()
    	{ // TODO requries delete __r.release() well-formed
    		__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    			typedef int _IsComplete[sizeof(_Tp1)];
    		_Tp1* __tmp = __r.get();
    		_M_refcount = __shared_count<_Lp>(__r);
    		__enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
    	}
    
    #endif
    
    	template<typename _tp1 = "">
    	__shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
    		: _M_ptr(static_cast<element_type*>(__r._M_ptr)),
    		_M_refcount(__r._M_refcount)
    	{ }
    
    	template<typename _tp1 = "">
    	__shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
    		: _M_ptr(const_cast<element_type*>(__r._M_ptr)),
    		_M_refcount(__r._M_refcount)
    	{ }
    
    	template<typename _tp1 = "">
    	__shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
    		: _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
    		_M_refcount(__r._M_refcount)
    	{
    		if (_M_ptr == 0) // need to allocate new counter -- the cast failed
    			_M_refcount = __shared_count<_Lp>();
    	}
    
    	template<typename _tp1 = "">
    	__shared_ptr& operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
    	{
    		_M_ptr = __r._M_ptr;
    		_M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
    		return *this;
    	}
    
    #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
    	template<typename _tp1 = "">
    	__shared_ptr& operator=(std::auto_ptr<_Tp1>& __r)
    	{
    		__shared_ptr(__r).swap(*this);
    		return *this;
    	}
    #endif
    
    	void reset() // never throws
    	{
    		__shared_ptr().swap(*this);
    	}
    
    	template<typename _tp1 = "">
    	void reset(_Tp1* __p) // _Tp1 must be complete.
    	{
    		// Catch self-reset errors.
    		_GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
    		__shared_ptr(__p).swap(*this);
    	}
    
    	template<typename _deleter = "" typename = "">
    	void reset(_Tp1* __p, _Deleter __d)
    	{
    		__shared_ptr(__p, __d).swap(*this);
    	}
    
    	// Allow class instantiation when _Tp is [cv-qual] void.
    	typename std::tr1::add_reference<_Tp>::type
    		operator*() const // never throws
    	{
    		_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
    		return *_M_ptr;
    	}
    
    	_Tp* operator->() const // never throws
    	{
    		_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
    		return _M_ptr;
    	}
    
    	_Tp* get() const // never throws
    	{
    		return _M_ptr;
    	}
    
    	// Implicit conversion to "bool"
    private:
    	typedef _Tp* __shared_ptr::*__unspecified_bool_type;
    
    public:
    	operator __unspecified_bool_type() const // never throws
    	{
    		return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr;
    	}
    
    	bool unique() const // never throws
    	{
    		return _M_refcount._M_unique();
    	}
    
    	long use_count() const // never throws
    	{
    		return _M_refcount._M_get_use_count();
    	}
    
    	void swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
    	{
    		std::swap(_M_ptr, __other._M_ptr);
    		_M_refcount._M_swap(__other._M_refcount);
    	}
    
    private:
    	void* _M_get_deleter(const std::type_info& __ti) const
    	{
    		return _M_refcount._M_get_deleter(__ti);
    	}
    
    	template<typename _lock_policy = "" _lp1 = "">
    	bool _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
    	{
    		return _M_refcount < __rhs._M_refcount;
    	}
    
    	template<typename _lock_policy = "" _lp1 = ""> friend class __shared_ptr;
    	template<typename _lock_policy = "" _lp1 = ""> friend class __weak_ptr;
    
    	template<typename _lock_policy = "" _lp1 = "" typename = "">
    	friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
    
    	// Friends injected into enclosing namespace and found by ADL:
    	template<typename _tp1 = "">
    	friend inline bool
    		operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
    	{
    		return __a.get() == __b.get();
    	}
    
    	template<typename _tp1 = "">
    	friend inline bool
    		operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
    	{
    		return __a.get() != __b.get();
    	}
    
    	template<typename _tp1 = "">
    	friend inline bool
    		operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
    	{
    		return __a._M_less(__b);
    	}
    
    	_Tp*             _M_ptr;         // Contained pointer.
    	__shared_count<_Lp>  _M_refcount;    // Reference counter.
    };
    
    
    // __shared_count
    template<_Lock_policy _Lp = __default_lock_policy>
    class __shared_count
    {
    public:
    	__shared_count()
    		: _M_pi(0) // nothrow
    	{ }
    
    	template<typename _ptr = "">
    	__shared_count(_Ptr __p) : _M_pi(0)
    	{
    		__try
    		{
    			typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp;
    			_M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>(
    				__p, _Sp_deleter<_Tp>());
    		}
    		__catch(...)
    		{
    			delete __p;
    			__throw_exception_again;
    		}
    	}
    
    	template<typename _deleter = "" typename = "">
    	__shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
    	{
    		__try
    		{
    			_M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
    		}
    		__catch(...)
    		{
    			__d(__p); // Call _Deleter on __p.
    			__throw_exception_again;
    		}
    	}
    
    	// Special case for auto_ptr<_Tp> to provide the strong guarantee.
    	template<typename _tp = "">
    	explicit
    		__shared_count(std::auto_ptr<_Tp>& __r)
    		: _M_pi(new _Sp_counted_base_impl < _Tp*,
    		_Sp_deleter<_Tp>, _Lp > (__r.get(), _Sp_deleter<_Tp>()))
    	{
    		__r.release();
    	}
    
    	// Throw bad_weak_ptr when __r._M_get_use_count() == 0.
    	explicit __shared_count(const __weak_count<_Lp>& __r);
    
    	~__shared_count() // nothrow
    	{
    		if (_M_pi != 0)
    			_M_pi->_M_release();
    	}
    
    	__shared_count(const __shared_count& __r)
    		: _M_pi(__r._M_pi) // nothrow
    	{
    		if (_M_pi != 0)
    			_M_pi->_M_add_ref_copy();
    	}
    
    	__shared_count& operator=(const __shared_count& __r) // nothrow
    	{
    		_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    		if (__tmp != _M_pi)
    		{
    			if (__tmp != 0)
    				__tmp->_M_add_ref_copy();
    			if (_M_pi != 0)
    				_M_pi->_M_release();
    			_M_pi = __tmp;
    		}
    		return *this;
    	}
    
    	void _M_swap(__shared_count& __r) // nothrow
    	{
    		_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    		__r._M_pi = _M_pi;
    		_M_pi = __tmp;
    	}
    
    	long _M_get_use_count() const // nothrow
    	{
    		return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0;
    	}
    
    	bool _M_unique() const // nothrow
    	{
    		return this->_M_get_use_count() == 1;
    	}
    
    	friend inline bool
    		operator==(const __shared_count& __a, const __shared_count& __b)
    	{
    		return __a._M_pi == __b._M_pi;
    	}
    
    	friend inline bool
    		operator<(const __shared_count& __a, const __shared_count& __b)
    	{
    		return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi);
    	}
    
    	void* _M_get_deleter(const std::type_info& __ti) const
    	{
    		return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0;
    	}
    
    private:
    	friend class __weak_count < _Lp > ;
    
    	_Sp_counted_base<_Lp>*  _M_pi;
    };
    
    // _Sp_counted_base
    template<_Lock_policy _Lp = __default_lock_policy>
    class _Sp_counted_base
    	: public _Mutex_base < _Lp >
    {
    public:
    	_Sp_counted_base()
    		: _M_use_count(1), _M_weak_count(1) { }
    
    	virtual	~_Sp_counted_base() // nothrow 
    	{ }
    
    	// Called when _M_use_count drops to zero, to release the resources
    	// managed by *this.
    	virtual void _M_dispose() = 0; // nothrow
    
    	// Called when _M_weak_count drops to zero.
    	virtual void _M_destroy() // nothrow
    	{
    		delete this;
    	}
    
    	virtual void* _M_get_deleter(const std::type_info&) = 0;
    
    	void _M_add_ref_copy()
    	{
    		__gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1);
    	}
    
    	void _M_add_ref_lock();
    
    	void _M_release() // nothrow
    	{
    		// Be race-detector-friendly.  For more info see bits/c++config.
    		_GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
    		if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
    		{
    			_GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
    			_M_dispose();
    			// There must be a memory barrier between dispose() and destroy()
    			// to ensure that the effects of dispose() are observed in the
    			// thread that runs destroy().
    			// See https://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
    			if (_Mutex_base<_Lp>::_S_need_barriers)
    			{
    				__atomic_thread_fence(__ATOMIC_ACQ_REL);
    			}
    
    			// Be race-detector-friendly.  For more info see bits/c++config.
    			_GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
    			if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
    				-1) == 1)
    			{
    				_GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
    				_M_destroy();
    			}
    		}
    	}
    
    	void _M_weak_add_ref() // nothrow
    	{
    		__gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1);
    	}
    
    	void _M_weak_release() // nothrow
    	{
    		// Be race-detector-friendly. For more info see bits/c++config.
    		_GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
    		if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
    		{
    			_GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
    			if (_Mutex_base<_Lp>::_S_need_barriers)
    			{
    				// See _M_release(),
    				// destroy() must observe results of dispose()
    				__atomic_thread_fence(__ATOMIC_ACQ_REL);
    			}
    			_M_destroy();
    		}
    	}
    
    	long _M_get_use_count() const // nothrow
    	{
    		// No memory barrier is used here so there is no synchronization
    		// with other threads.
    		return const_cast<const volatile = "">(_M_use_count);
    	}
    
    private:
    	_Sp_counted_base(_Sp_counted_base const&);
    	_Sp_counted_base& operator=(_Sp_counted_base const&);
    
    	_Atomic_word  _M_use_count;     // #shared
    	_Atomic_word  _M_weak_count;    // #weak + (#shared != 0)
    };
    

    End ----------------------------------------------------------------------------------------------------

    展开全文
  • stl中auto_ptr,unique_ptr,shared_ptr,weak_ptr四种智能指针使用总结 stl中auto_ptr,unique_ptr,shared_ptr,weak_ptr四种智能指针使用总结   1. auto_ptr auto_ptr主要是用来解决资源自动释放的问题,比如如下...
  •   C++里面的四个智能指针: auto_ptr, shared_ptr, weak_ptr, unique_ptr 其中后三个是C++11支持,并且第一个已经被11弃用。 为什么要用智能指针   智能指针的作用是管理一个指针,因为存在以下这种情况:申请的...
  • C++11的智能指针shared_ptrweak_ptr源码解析

    万次阅读 多人点赞 2021-05-06 22:01:31
    C++智能指针shared_ptr源码解析1、前言2、...本文仅对C++智能指针shared_ptrweak_ptr源码进行解析,需要读者有一定的C++基础并且对智能指针有所了解,但是本文不对智能指针的使用方法、使用场景、效率等方面进行阐述
  • 随着计算机技术的发展,在boost准标准库的推动下,C++11终于将unique_ptr、shared_ptrweak_ptr这几类智能指针纳入C++中。当然,在这之前还有一种auto_ptr智能指针,不过由于它的设计存在较大问题(比如:auto_ptr...
  • 原理二、shared_ptr使用1.构造以及简单使用2.常用方法3.错误用法三、weak_ptr介绍1.weak_ptr特点2.使用weak_ptr目的四、weak_ptr的使用1.方法2.使用实例总结 前言 前几天对于智能指针写了个详细介绍,对于unique_ptr...
  • 智能指针 auto_ptr、scoped_ptr、shared_ptrweak_ptr  什么是RAII? RAII是Resource Acquisition Is Initialization的简称,是C++语言的一种管理资源、避免泄漏的惯用法。 RAII又叫做资源分配即初始化,即:...
  • c++中的smart pointer四个智能指针: shared_ptr,unique_ptr,weak_ptr,auto_ptr C++里面的四个智能指针: auto_ptr, shared_ptr, weak_ptr, unique_ptr其中后三个是c++11支持,并且第一个已经被11弃用。 为什么要...
  • * unique_ptr, shared_ptr, weak_ptr 和C++11中已经废弃的auto_ptr,在C++17中被正式删除 * * 几种智能指针: * 1. 应用场景: * 1:对象所有权 * 2. 生命周期 * 2. 性能分析: * * */ #include<...
  • stl中auto_ptr,unique_ptr,shared_ptr,weak_ptr四种智能指针的使用总结 (1)auto_ptr 主要用于解决资源自动释放的问题。防止用户忘记delete掉new申请的内存空间。使用auto_ptr会在离开变量的作用域之后直接调用析...
  • C++中的四个智能指针shared_ptr, weak_ptr, unique_ptr, auto_ptr 其中前面三个是C++11支持并且最后一个已经被C++11抛弃。 智能指针的作用是管理一个指针,因为存在以下这种情况:申请的空间在函数结束时忘记释放,...
  • auto_ptr 先用一道题说明auto_ptr的不足: 问题:为什么vector中的元素不可以是auto_ptr的对象? 原因很简单,vector是将对象拷贝一份,然后放入,而对auto_ptr进行...一般来说,智能指针的实现需要以下步骤: 1.一个模
  • 原文转载于:https://blog.csdn.net/zsc_976529378/article/details/52250597在一次面试过程中被问到了stl中的四种... 然后面试官就提示是weak_ptr,之后他又主动说出了unique_ptr我也只对auto_ptr和shared_ptr做了...
  • C++ 智能指针(shared_ptr/weak_ptr)源码 源码位置:gcc-6.1.0\gcc-6.1.0\libstdc++-v3\include\tr1 这里只单列shared_ptr.h文件用于分析
  • weak_ptr shared_ptr的弱引用 shared_ptr描述(in memory): shared_ptr是一个标准的共享所有权的智能指针,就是允许多个指针指向同一对象,shared_ptr对象中不仅有一个指针指向某某(比如 int型,以下也拿int类型举例...
  • C++里面的四个智能指针: auto_ptr, shared_ptr, weak_ptr, unique_ptr 其中后三个是c++11支持,并且第一个已经被11弃用。 为什么要使用智能指针: 智能指针的作用是管理一个指针,因为存在以下这种情况:申请的...
  •  智能指针自动释放原理:1 离开作用域,2 引用计数为零,内存释放。 作用域释放适用于unique_ptr。 shared_ptr,应满足两个条件,离开作用域且引用计数为零。unique_ptr 作用域范围内唯一指针,不可被复制或着...
  • C++里面的四个智能指针: auto_ptr, shared_ptr, weak_ptr, unique_ptr 其中后三个是c++11支持,并且第一个已经被11弃用。 为什么要使用智能指针: 智能指针的作用是管理一个指针,因为存在以下这种情况:申请的空间...
  • 智能指针---shared_ptrweak_ptr

    千次阅读 2016-06-20 11:46:13
    下面介绍一下boost库中的shared_ptrweak_ptr:Shared_ptr:当进行拷贝和赋值操作时, shared_ptr所指向的对象的引用计数都会增加,一旦变为0,就会自动释放自己管理的对象。(shared_ptr所指向的对象有一个被释放时...
  • auto_ptr实现原理其实就是RAII,在构造的时候获取资源,在析构的时候释放资源,并进行相关指针操作的重载,使用起来就像普通的指针。 对于编译器来说,智能指针实质是一个栈对象,而并非指针类型。 智能指针...
  • 智能指针(三):weak_ptr浅析

    万次阅读 多人点赞 2018-09-01 14:36:26
    weak_ptr这个指针天生一副“小弟”的模样,也是在C++11的时候引入的标准库,它的出现完全是为了弥补它老大shared_ptr天生有缺陷的问题,其实相比于上一代的智能指针auto_ptr来说,新进老大shared_ptr可以说近乎完美...
  • boost智能指针之shared_ptrweak_ptr

    千次阅读 2015-01-29 09:09:07
    std::auto_ptr很多的时候并不能满足我们的要求,比如auto_ptr不能用作STL容器的元素。boost的smart_ptr中提供了4种智能指针和2种智能指针数组来作为std::auto_ptr的补充。...weak_ptrweak_ptr 是 shared_ptr 的观察员
  • auto_ptr 特点:只能作用于一个对象,一个对象只需要开辟空间,由它进行内存的管理。 unique_ptr 特点:只能作用于一个对象,可以通过移动构造和移动赋值进行分转移。 scoped_ptr 特点:局部的,既不是可...
  • 在C++ 11标准中出现了新的智能指针unique_ptr、 shared_ptrweak_ptr等 一、unique_ptr 特点:所有权唯一,禁止拷贝和权限转移 缺点:unique_ptr是简单粗暴的防止拷贝,这种比较简单,效率高,但是功能不全面,...
  • weak_ptr源码分析

    2020-08-09 11:05:56
    在经历过shared_ptr源码分析之后,我们接下来继续分析weak_ptrweak_ptr是作为shared_ptr的补充而出现的,用于避免循环引用问题。 weak_ptr结构与shared_ptr近乎一致,这里直接写出部分结构和关键函数。 weak_ptr&...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,412
精华内容 1,764
关键字:

weak_ptr实现原理