精华内容
下载资源
问答
  • share_ptr

    2019-08-11 21:42:32
    1、为了保证不会重复释放内存,auto_...2、auto_ptr的问题就是,一块内存只能有一个指针指向它,为了解决这个问题,使用share_ptr。 3、share_ptr是如何实现的?  a、内部有一个指向原始资源的指针。  b、内部...

    1、为了保证不会重复释放内存,auto_ptr的copy构造和copy赋值都是破坏性操作,执行后,导致右操作数的指针为0。这就出现了,copy构造或者copy赋值后,两个对象不相等了。

    2、auto_ptr的问题就是,一块内存只能有一个指针指向它,为了解决这个问题,使用share_ptr。

    3、share_ptr是如何实现的?

      a、内部有一个指向原始资源的指针。

      b、内部维护一个share_count,记录有多少个指针指向该内存。

      c、析构的时候,share_count>1,将计数减1;share_count==1释放内存。

      d、考虑到每个share_ptr中都有一个自己的share_count,而且还要保证这个数一致,应该这样做:先对原始资源封装,加入share_count,成为带有count的资源,share_count在对它封装,这样就可以只有一个share_count了。

      e、copy构造的时候,lhs的指针指向rhs的资源,share_count加1。

      f、copy赋值的时候,先检查左操作数原来的资源是否可以释放,lhs的指针指向rhs的资源,share_count加1。

    转载于:https://www.cnblogs.com/nzbbody/p/3381071.html

    展开全文
  • Share_ptr

    2017-11-23 21:55:39
    Share_ptr也是一种智能指针。类比于auto_ptr学习。所以推荐先学习auto_ptr,再来学习shared_ptr。本博客的前两个就是auto_ptr的总结。希望感兴趣的朋友可以看看。   Shared_ptr和auto_ptr最大的区别就是,...

    Share_ptr也是一种智能指针。类比于auto_ptr学习。所以推荐先学习auto_ptr,再来学习shared_ptr。本博客的前两个就是auto_ptr的总结。希望感兴趣的朋友可以看看。

     

    Shared_ptr和auto_ptr最大的区别就是,shared_ptr解决了指针间共享对象所有权的问题,也就是auto_ptr中的赋值的奇怪问题。所以满足了容器的要求,可以用于容器中。而auto_ptr显然禁止共享对象所有权,不可以用于容器中。

    [cpp]  view plain  copy
    1. int * a=new int(2);  
    2. shared_ptr<int> sp1(a);  
    3. shared_ptr<int> sp2(sp1);     OK  

    当然shared_ptr作为一种智能指针,也拥有和shared_ptr一些相似的性质。它们本质上都是类,但是使用起来像指针。它们都是为了解决防止内存泄漏的解决方案。都是运用了RAII技术来实现的。

     

    注意:使用shared_ptr也要引用头文件#include<memory>

     

    由于shared_ptr的源码过于复杂,我们不给出源码。类比于auto_ptr学习.

     

    1. 首先类shared_ptr有两个成员变量。T * px和unsign long * pn;

    T * px;显然和auto_ptr一样,用于储存对象的指针。

    pn用于记录有多少个shared_ptr拥有同一个对象。pn是shared_ptr对象间共享的,类似于static成员变量。 

    [cpp]  view plain  copy
    1. template<class T>  
    2. class shared_ptr{  
    3. private:  
    4.        T *px; // contained pointer  
    5.     unsignedlong* pn; // reference counter  
    6. }  

    总结:其实shared_ptr的原理,就是使用px来记录指针,使用*pn来记录px指向的对象的拥有者share_ptr的个数,当一个shared_ptr对象达到作用域时,不会释放资源,只有当*pn变为0的时候,才会释放指针指向的资源。

     

    2. 一个简单实现的源码(仍然看懂源码还是最重要的。

    [cpp]  view plain  copy
    1. #pragma once  
    2. //shared_ptr的简单实现版本  
    3. //基于引用记数的智能指针  
    4. //它可以和stl容器完美的配合  
    5. namespace boost  
    6. {  
    7. template<class T>  
    8. class shared_ptr  
    9. {  
    10. typedef unsigned longsize_type;  
    11. private:  
    12.        T *px; // contained pointer  
    13.    size_type* pn; // reference counter  
    14. public:  
    15. //构造函数---------------------------------------------------2  
    16. /* 
    17. int* a=new int(2); 
    18. shared_ptr<int> sp; 
    19. shared_ptr<int> sp(a); 
    20. */  
    21. explicitshared_ptr(T* p=0) : px(p)  
    22. {  
    23.    pn = new size_type(1);  
    24. }  
    25.    
    26. /* 
    27. Derived d; 
    28. shared_ptr<Base> ap(d); 
    29. */  
    30. template<typename Y>  
    31. shared_ptr(Y* py)  
    32. {  
    33. pn = newsize_type(1);  
    34. px=py;  
    35. }  
    36. //copy构造函数------------------------------------------------  
    37. /* 
    38. int * a=new int; 
    39. shared_ptr<int> sp(a); 
    40. shared_ptr<int> sp1(sp); 
    41. */  
    42. shared_ptr(constshared_ptr& r) throw(): px(r.px)  
    43. {  
    44. ++*r.pn;  
    45. pn = r.pn;  
    46. }  
    47.    
    48. /* 
    49. shared_ptr<Derived>sp1(derived); 
    50. shared_ptr<Base> sp2(sp1); 
    51. */  
    52. template<typename Y>  
    53. shared_ptr(constshared_ptr<Y>& r)//用于多态  
    54. {  
    55. px = r.px;  
    56. ++*r.pn;  
    57. pn = r.pn; //shared_count::op= doesn't throw  
    58. }  
    59. //重载赋值operator=--------------------------------------------  
    60. shared_ptr& operator=(const shared_ptr& r) throw()  
    61. {  
    62. if(this== &r) return *this;  
    63. dispose();  
    64. px = r.px;  
    65. ++*r.pn;  
    66. pn = r.pn;  
    67. return *this;  
    68. }  
    69. template<typename Y>  
    70. shared_ptr& operator=(const shared_ptr<Y>& r)//用于多态  
    71. {  
    72. dispose();  
    73. px = r.px;  
    74. ++*r.pn;  
    75. pn = r.pn; //shared_count::op= doesn't throw  
    76. return *this;  
    77. }  
    78.    
    79. ~shared_ptr() { dispose(); }  
    80. void reset(T* p=0)  
    81. {  
    82. if ( px == p ) return;  
    83. if (--*pn == 0)  
    84. delete(px); }  
    85. else  
    86. // allocate newreference  
    87. // counter  
    88. // fix: prevent leak if new throws  
    89. try { pn = new size_type; }  
    90. catch (...) {  
    91. // undo effect of —*pn above to  
    92. // meet effects guarantee  
    93. ++*pn;  
    94. delete(p);  
    95. throw;  
    96. // catch  
    97. // allocate newreference counter  
    98. *pn = 1;  
    99. px = p;  
    100. // reset  
    101. reference operator*()const throw(){ return *px; }  
    102. pointer operator->()const throw(){ return px; }  
    103. pointer get() constthrow(){ returnpx; }  
    104. size_type use_count() constthrow()//  
    105. return *pn; }  
    106. bool unique() const throw()//  
    107. return *pn ==1; }  
    108. private:  
    109. void dispose() throw()  
    110. {  
    111. if (--*pn == 0)  
    112. delete px; delete pn; }  
    113. }  
    114. }; // shared_ptr  
    115. template<typename A,typenameB>  
    116. inline bool operator==(shared_ptr<A>const & l, shared_ptr<B> const & r)  
    117. {  
    118. return l.get() == r.get();  
    119. }  
    120. template<typename A,typenameB>  
    121. inline bool operator!=(shared_ptr<A>const & l, shared_ptr<B> const & r)  
    122. {  
    123. return l.get() != r.get();  
    124. }  
    125. }//namespace boost  


    要注意的地方:

     

    3. Shared_ptr和auto_ptr都有类似的规定:

    看看它们的copy构造和重载赋值都可以看出:

    不允许

    [cpp]  view plain  copy
    1. int* a=new int(2);  
    2. shared_ptr<int>sp=a;//  error  
    3. sp=a;//    error  

    就是不允许使用一个纯指针给一个智能指针赋值或copy构造。只能使用智能指针给另一个智能指针赋值或copy构造。

    [cpp]  view plain  copy
    1.    int* a=new int(2);  
    2. hared_ptr<int> sp(a);//构造函数  
    3. shared_ptr<int> sp1(sp);//copy构造  
    4.    sp1=sp;//赋值  

    在auto_ptr中也是相同的。

     

    4. 注意shared_ptr的几个函数

    Ø     Reset()函数:重置函数

    标准中的是:

    [cpp]  view plain  copy
    1.    int* a=new int(2);  
    2.     int* b=new int(3);  
    3.  shared_ptr<int> sp2(a);  
    4.  shared_ptr<int> sp1(a);  
    5. shared_ptr<int> sp(a);  
    6.     sp.reset(b);  
    7.    sp.reset();  
    8.    sp.reset(sp2);  -----!!!也是可以的。  

    使得sp获得b的拥有权。失去a的拥有权。注意这会使得a的拥有者少1.当a的拥有者变为0时,就会释放a的资源。

    Ø     Swap()函数:交换函数

    [cpp]  view plain  copy
    1. int* a=new int(2);  
    2. shared_ptr<int> sp(a);  
    3. shared_ptr<int> sp1(a);  
    4. sp.swap(sp1);  

    就是两个shared_ptr中的px和pn都互换一下。

    Ø     Get()函数:返回px

    Ø     Use_count函数:返回*pn,就是对象的拥有者的数量。

    Ø     Unique函数:令*pn=1;让对象的拥有者的数量变为1。返回bool

    Ø     同时share_ptr也重载了*和->

     

    5. tr1中重载了几个有关shared_ptr的符号:

    template<classT, class U>

    booloperator==(shared_ptr<T> const& a, shared_ptr<U> const& b);

    判断拥有的对象是否是一样的

     

    template<classT, class U>

     bool operator!=(shared_ptr<T> const&a, shared_ptr<U> const& b);

    判断拥有的对象是否是不一样的

     

    template<classT, class U>

     bool operator<(shared_ptr<T>const& a, shared_ptr<U> const& b);

    重载了小于号,在STL中的LIST中非常有用。

    [cpp]  view plain  copy
    1. int* a=new int(2);  
    2. int* b=new int(3);  
    3. shared_ptr<int> sp(a);  
    4. shared_ptr<int> sp1(b);  
    5. if(sp<sp1)  
    6.        cout<<"2222"<<endl;  

    6. 注意真实中shared_ptr中没有public dispose这个函数,这里只是为了避免代码重复。

     

    7. 注意shared_ptr中的析构函数中不是直接释放资源,而是调用了dispose函数,如果*pn==0了,才会释放资源。

     

    8.shared_ptr的多线程的安全性

    shared_ptr 本身不是 100%线程安全的。它的引用计数本身是安全且无锁的,但对象的读写则不是,因为shared_ptr有两个数据成员,读写操作不能原子化。根据文档shared_ptr的线程安全级别和内建类型、标准库容器、string一样,即:

    • 一个 shared_ptr 实体可被多个线程同时读取;
    • 两个的 shared_ptr 实体可以被两个线程同时写入,“析构”算写操作;
    • 如果要从多个线程读写同一个 shared_ptr 对象,那么需要加锁。

     

    发现了两个非常有意思的东西:

    1. 看tr1中的源码中发现两个这样的东西:

    template<class Y, classD> shared_ptr(Y * p, D d);

    template<class Y, classD> void reset(Y * p, D d);

    其中的D d是个什么东西?源码的解释是d是一个deleter(删除器)。至此我们突然发现我们可以给shared_ptr指定一个删除器,当*pn==0的时候,不去释放资源,而去调用我们自己给它的删除器。

     

    当shared_ptr的引用次数为0的时候,share_ptr就会调用释放函数来释放资源。

    当我们希望引用次数为0的时候,shared_ptr不释放资源,而是调用我们指定的操作的时候,就会用到D d;

    [cpp]  view plain  copy
    1. void foo(int * d)  
    2. {  
    3.        cout<<"1234"<<endl;  
    4. }  
    5.    
    6. int _tmain(int argc, _TCHAR* argv[])  
    7. {  
    8.        int* a=new int(2);  
    9.        shared_ptr<int> sp(a,foo);  
    10.        shared_ptr<int> sp1(sp);  
    11.        sp.reset();  
    12.        sp1.reset();  
    13.        //_CrtDumpMemoryLeaks();  
    14.        system("pause");  
    15.        return 0;  
    16. }  


    注意!:

    1. 指定的删除器的参数必须是int*;和shared_ptr<int>中的int对应。不能是其他的,或者为空也是错的。因为系统会把shared_ptr的对象px赋给删除器的参数,我们也可以在删除器中释放资源。

    2. 只有a的引用次数为0才会调用,所以如果没有sp1.reset()。也不会调用foo函数。

     

    2. 使用shared_ptr的时候,要小心,想一想操作的内在含义才去做。

    1>

    [cpp]  view plain  copy
    1. int* a=new int(2);  
    2. shared_ptr<int> sp(a);  
    3. shared_ptr<int> sp1(sp);  
    4. sp.reset();//--------(1)  
    5. sp.reset();//--------(2)  


    这里(1)是重置了sp,注意(2)是没有任何作用的,不能使得a的引用次数变为0.想一想reset的函数内部,(2)的时候,sp中的对象pn已经为空了,则不能改变*pn的值了。

     

    2>

    [cpp]  view plain  copy
    1. int* a=new int(2);  
    2.   shared_ptr<int> sp(a);//----------(1)  
    3.   shared_ptr<int> sp1(a);//---------(2)  

    注意:这里的(2)也是不对的。想一想shared_ptr的构造函数,(1)的时候,sp的px指向a,且*pn为1.而(2)的时候,px指向a,且*pn也是1.这显然就问题了。a被引用了2次,但是*pn为1.在最后作用域达到的时候,就会释放2次内存,这就会引发异常。

     

    总结:shared_ptr和auto_ptr的区别。

    Shared_ptr有两个变量,一个记录对象地址,一个记录引用次数

    Auto_ptr只有一个变量,用来记录对象地址

     

    Shared_ptr可用多个shared_ptr拥有一个资源。

    Auto_ptr只能一个auto_ptr拥有一个资源

     

    Shared_ptr可以实现赋值的正常操作,使得两个地址指向同一资源

    Auto_ptr的赋值很奇怪,源失去资源拥有权,目标获取资源拥有权

     

    Shared_ptr到达作用域时,不一定会释放资源。

    Auto_ptr到达作用于时,一定会释放资源。

     

    Shared_ptr存在多线程的安全性问题,而auto_ptr没有。

     

    Shared_ptr可用于容器中,而auto_ptr一般不可以用于容器中。


    Shared_ptr可以在构造函数、reset函数的时候允许指定删除器。而auto_ptr不能。

     

    还有这里说一句:使用智能指针(不管shared_ptr还是auto_ptr),都要清除源码内部的实现原理,使用起来才不会错。而且使用的时候,一定要想一想函数内部的实现原理再去使用。切记小心。

    展开全文
  • unique_ptrshare_ptr的实现原理

    unique_ptr和share_ptr的简单实现

    unique_ptr的简单实现

    来自
    实现智能指针1:unique_ptr
    下面列出需要注意的知识点:
    1.异常
    2.unique_ptr本身功能
    3.三五法则和阻止拷贝
    4.隐式的类类型转换
    5.移动构造、移动赋值及自赋值问题
    6.编写模板类。

    //reference: https://www.jianshu.com/p/77c2988be336
    //第一次错误:在模板类外定义成员函数时,需要声明template<typename T>
    //         同时应该是 返回值 类<T>:: 成员函数(参数){}这种格式
    
    template<typename T>
    class MyUniquePtr{
    public:
        //显式构造
        explicit MyUniquePtr(T* ptr=nullptr):mPtr(ptr){
        }
        ~MyUniquePtr(){
            if(mPtr!=nullptr)
                delete mPtr;
        }
        //移动构造,注意右值引用p会被修改,所以不能用const
        MyUniquePtr(MyUniquePtr&& p) noexcept;
        //移动赋值,同理不能用const
        MyUniquePtr& operator=(MyUniquePtr&& p) noexcept;
    
        //禁止赋值构造和赋值运算符
        MyUniquePtr(const MyUniquePtr& p)=delete;
        MyUniquePtr& operator=(const MyUniquePtr& p)=delete;
         
    
        //重载指针的功能
        T* operator->()const noexcept{
            return mPtr;
        }
        T& operator*()const noexcept{
            return *mPtr;
        }
    
    
        //使MyUniquePtr能够根据上下文转换为bool类型
        explicit operator bool() const noexcept{
            return mPtr;
        }
    
        //释放原来的空间,然后指向新的地址空间
        void reset(T* q=nullptr) noexcept{
            if(mPtr!=q){
                if(mPtr!=nullptr)
                    delete mPtr;
                mPtr=q;
            }
        }
    
        //指针置nullptr,原先地址作为返回值返回
        T* release() noexcept{
            T* res=mPtr;
            mPtr=nullptr;
            return res;
        }
        
        //返回内部指针
        T* get()const noexcept{
            return mPtr;
        }
    
    /*
    了解一下std::swap的一些特性
    1.大概全貌如下:
    template<typename T>
    void swap(T &a,T &b) noexcept
    {
        T temp = std::move(a);
        a = std::move(b);
        b = std::move(temp);
    }
    2.要求T必须满足MoveAssignable和MoveConstructible
      通俗讲就是有移动构造函数和移动赋值函数
    */
        void swap(MyUniquePtr& p) noexcept{
            using std::swap;
            swap(mPtr,p.mPtr);
        }
    
    
    private:
        T* mPtr;
    };
    
    
    //移动构造函数(Move Constructors)和移动赋值运算符( Move Assignment Operator)从给定对象窃取资源而不是拷贝资源
    template<typename T>
    MyUniquePtr<T>::MyUniquePtr(MyUniquePtr&& p) noexcept: mPtr(p.mPtr){
        p.mPtr=nullptr;
    }
    
    //这里用swap来避免 在实现赋值运算符是需要检查自我赋值的情况
    //https://www.geeksforgeeks.org/copy-swap-idiom-c/
    template<typename T>
    MyUniquePtr<T>& MyUniquePtr<T>::operator=(MyUniquePtr&& p) noexcept{
        swap(p);
        return *this;
    }
    

    shared_ptr的简单实现

    来自
    实现一个简单的shared_ptr

    一般来说,智能指针的实现需要以下步骤:
    1.一个模板指针T* ptr,指向实际的对象。
    2.一个引用次数(必须new出来的,不然会多个shared_ptr里面会有不同的引用次数而导致多次delete)。
    3.重载operator*和operator->,使得能像指针一样使用shared_ptr。
    4.重载copy constructor,使其引用次数加一。
    5.重载operator=,如果原来的shared_ptr已经有对象,则让其引用次数减一并判断引用是否为零(是否调用delete)。
     然后将新的对象引用次数加一。
    6.重载析构函数,使引用次数减一并判断引用是否为零(是否调用delete)。

    #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
    
    展开全文
  • weakptr的作为弱引用指针,其实现依赖于counter的计数器类和share_ptr的赋值,构造,所以先把counter和share_ptr简单实现 Counter简单实现 class Counter { public: Counter() : s(0), w(0){}; int s; //share_ptr...

    weakptr的作为弱引用指针,其实现依赖于counter的计数器类和share_ptr的赋值,构造,所以先把counter和share_ptr简单实现

    Counter简单实现

    class Counter
    {
    public:
        Counter() : s(0), w(0){};
        int s;	//share_ptr的引用计数
        int w;	//weak_ptr的引用计数
    };
    

    counter对象的目地就是用来申请一个块内存来存引用基数,s是share_ptr的引用计数,w是weak_ptr的引用计数,当w为0时,删除Counter对象。

    share_ptr的简单实现

    template <class T>
    class WeakPtr; //为了用weak_ptr的lock(),来生成share_ptr用,需要拷贝构造用
    
    template <class T>
    class SharePtr
    {
    public:
        SharePtr(T *p = 0) : _ptr(p)  // 构造函数传入所管理对象的指针
        {
            cnt = new Counter();  // 新建Counter对象
            if (p)  // 对象指针不为nullptr
                cnt->s = 1;  // 引用计数器初值
            cout << "in construct " << cnt->s << endl;
        }
        ~SharePtr()  // 析构函数
        {
            release();  // 释放所管理对象,如果引用计数为0则回收所管理对象对应内存空间
        }
    
        SharePtr(SharePtr<T> const &s)  // 拷贝构造函数
        {
            cout << "in copy con" << endl;
            _ptr = s._ptr;  // 复制对象指针
            (s.cnt)->s++;  // 原share_ptr对象引用计数自增
            cout << "copy construct" << (s.cnt)->s << endl;
            cnt = s.cnt;  // 复制Counter对象
        }
        SharePtr(WeakPtr<T> const &w) //为了用weak_ptr的lock(),来生成share_ptr用,需要拷贝构造用
        {
            cout << "in w copy con " << endl;
            _ptr = w._ptr;  // 复制weak_ptr管理对象的指针
            (w.cnt)->s++;  // 引用计数自增
            cout << "copy w  construct" << (w.cnt)->s << endl;
            cnt = w.cnt;  // 复制Count对象
        }
        SharePtr<T> &operator=(SharePtr<T> &s)  // =运算符重载
        {
            if (this != &s)  // 防止自我引用,导致引用计数增加
            {
                release();  // 先释放原管理对象的所有权
                (s.cnt)->s++;  // 引用计数自增
                cout << "assign construct " << (s.cnt)->s << endl;
                cnt = s.cnt;  // 复制Count对象
                _ptr = s._ptr;  // 复制新管理对象的指针
            }
            return *this;
        }
        T &operator*()  // 重载*运算符
        {
            return *_ptr;
        }
        T *operator->()  // 重载->运算符
        {
            return _ptr;
        }
        friend class WeakPtr<T>; // 方便weak_ptr与share_ptr设置引用计数和赋值
    
    protected:
        void release()  // 释放原管理对象所有权,若引用计数为0,回收所管理对象的内存
        {
            cnt->s--;  // 引用计数减1
            cout << "release " << cnt->s << endl;
            if (cnt->s < 1)
            {
                delete _ptr;
                if (cnt->w < 1)
                {
                    delete cnt;
                    cnt = NULL;
                }
            }
        }
    
    private:
        T *_ptr;  // 所管理对象的指针
        Counter *cnt;  // 每个share_ptr都有独立的的引用计数器,同一个管理对象所对应的所有share_ptr中的计数值一致
    };
    

    share_ptr的给出的函数接口为:构造,拷贝构造,赋值,解引用,通过release来在引用计数为0的时候删除_ptr和cnt的内存。

    weak_ptr简单实现

    template <class T>
    class WeakPtr
    {
    public: //给出默认构造和拷贝构造,其中拷贝构造不能有从原始指针进行构造
    	WeakPtr()  // 默认构造
    	{
    		_ptr = 0;
    		cnt = new Count();
    	}
    	WeakPtr(SharePtr<T> &s) : _ptr(s._ptr), cnt(s.cnt)  // 通过share_str拷贝构造
    	{
    		cout << "w con s" << endl;
    		cnt->w++;  // 为所管理对象的weak_ptr计数
    	}
    	WeakPtr(WeakPtr<T> &w) : _ptr(w._ptr), cnt(w.cnt)  // 通过weak_str拷贝构造
    	{
    		cnt->w++;  // 为所管理对象的weak_ptr计数
    	}
    	~WeakPtr()
    	{
    		release();
    	}
    	WeakPtr<T> &operator=(WeakPtr<T> &w)  // 通过weak_ptr赋值
    	{
    		if (this != &w)  // 防止自我赋值
    		{
    			release();  // 释放原管理对象
    			cnt = w.cnt;
    			cnt->w++;
    			_ptr = w._ptr;
    		}
    		return *this;
    	}
    	WeakPtr<T> &operator=(SharePtr<T> &s)  // 通过share_ptr赋值
    	{
    		cout << "w = s" << endl;
    		release();
    		cnt = s.cnt;
    		cnt->w++;
    		_ptr = s._ptr;
    		return *this;
    	}
    	SharePtr<T> lock()  // lock方法将weak_ptr转换为share_ptr
    	{
    		return SharePtr<T>(*this);  // 调用share_ptr的拷贝构造
    	}
    	bool expired()  // 判断所管理对象是否被释放
    	{
    		if (cnt)  // Count指针非空
    		{
    			if (cnt->s > 0)  // 引用计数不为0,返回false
    			{
    				cout << "empty" << cnt->s << endl;
    				return false;
    			}
    		}
    		return true;  // 其他返回true
    	}
    	friend class SharePtr<T>; //方便weak_ptr与share_ptr设置引用计数和赋值
    
    protected:
    	void release()
    	{
    		if (cnt)
    		{
    			cnt->w--;  // weak_ptr计数减1
    			cout << "weakptr release" << cnt->w << endl;
    			if (cnt->w < 1 && cnt->s < 1)  // weak_ptr与share_ptr计数均为0
    			{
    				//delete cnt;
    				cnt = NULL;
    			}
    		}
    	}
    
    private:
    	T *_ptr;
    	Counter *cnt;
    };
    

    weak_ptr一般通过share_ptr来构造,通过expired函数检查原始指针是否为空,lock来转化为share_ptr。

    展开全文
  • 1、智能指针的原理: 智能...2、常用的智能指针: auto_ptrshare_ptr、 unique_ptr, 智能指针的使用需要包含头文件#include&lt;memory&gt; 。3、智能指针使用需要注意的问题: (1)、避免删除非堆内存...
  • R.24:使用std::weak_ptr打破share_ptrs造成的循环 Reason(原因) shared_ptr's rely on use counting and the use count for a cyclic structure never goes to zero, so we need a mechanism to be able to ...
  • auto_ptr 相对于普通指针分配内存,需要自己new and delete,若不delete,就会造成内存泄露。auto_ptr智能指针可以做到,指针失效时自动回收内存空间。该指针可以进行复制构造与赋值构造,所以可能造成两个(或多个...
  • share_ptr 共享智能指针,从名字就能知道,它是一个共享的指针,也就说开辟一块堆空间,大家一起共用。 那我们怎么去管理这片共有的内存呢?share_ptr是一个模板类,在它里面有个成员count,专门用来记录有多少个...
  • C++11学习之share_ptr和weak_ptr

    千次阅读 2016-08-14 17:53:18
    一、shared_ptr学习1.shared_ptr和weak_ptr 基础概念 shared_ptr与weak_ptr智能指针均是C++ RAII的一种应用,可用于动态资源管理 shared_ptr基于“引用计数”模型实现,多个shared_ptr可指向同一个动态对象,并维护...
  • 在之前介绍了我们自己实现的ScopPtr和SharePtr,今天来看一下库里面的智能指针的实现由于历史原因,C++98中只实现了auto_ptrm而且还不好用,所以就有大佬们自己实现了share_ptr scoped_ptr 包含于第三方boost库中,...
  • share_ptr与weak_ptr的区别与联系

    千次阅读 2019-04-23 20:57:37
    1.shared_ptr和weak_ptr 基础概念 shared_ptr与weak_ptr智能指针均是C++ RAII的一种应用,可用于动态资源管理 shared_ptr基于“引用计数”模型实现,多个shared_ptr可指向同一个动态对象,并维护了一个共享的引用...
  • share_ptr使用

    2020-05-24 21:33:48
    内存管理之share_ptr引子初始化 sahred_ptr关于get()函数关于make_shared函数:shared_ptr的拷贝和赋值容器中的shared...
  • 深入分析shared_ptr与weak_ptr的实现 stl中使用了shared_ptr来管理一个对象的内部指针,并且使用了weak_ptr来防止前面所提到的shared_ptr循环引用的问题。 接下来简单的分析shared_ptr和weak_ptr的实现,最后通过...
  • share_ptr 浅析

    2020-12-17 18:05:46
    众所周知,share_ptr 的亮点就是 引用计数。 注意点一: 一个基本指针初始化多个 share_ptr , 这样会导致二次销毁。 int main() { int *p = new int; //基本指针 std::shared_ptr<int> p1(p); //函数...
  • C++ 智能指针 share_ptr

    2020-11-28 12:01:31
    share_ptr的本质还是指针,只不过赋予了一些“智能”的属性,导致其声明和使用方法发生了一些调整。这个智能的属性最大的特点就是不需要自己管理内存释放(delete)了,它是个成熟的指针,可以自己管理自己了。 2 ...
  •  auto_ptr是现在标准库里面一个轻量级的智能指针的实现,存在于头文件 memory中,之所以说它是轻量级,是因为它只有一个成员变量(拥有对象的指针),相关的调用开销也非常小。关于auto_ptr的使用,其通过构造函数...
  • Share_ptr 智能指针

    千次阅读 2018-05-15 21:03:19
    Share_ptr也是一种智能指针。类比于auto_ptr学习。所以推荐先学习auto_ptr,再来学习shared_ptr。本博客的前两个就是auto_ptr的总结。希望感兴趣的朋友可以看看。 Shared_ptr和auto_ptr最大的区别就是,shared_ptr...
  • 类-share_ptr实现原理

    千次阅读 2018-02-09 10:51:34
    1.引用计数管理内存的原理C++新标准库中采两个智能指针类型来管理动态对象,share_ptr允许多个指针指向同一个对象;unique_ptr则“独占”所指对象。对于share_ptr&lt;T&gt;我们可以按如下方式使用去管理堆...
  • 主要介绍了C++ 中boost::share_ptr智能指针的使用方法的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下
  • share_ptr 的 知识梳理

    千次阅读 2017-05-11 17:29:18
    share_ptr 的 知识梳理笔记 最近学习share_ptr 的时候发现这是个很有用的智能指针,无论是内存管理还是线程安全,以及自定义删除器, 所以觉得还是记录分享一下,同时也巩固一下自己的学习成果 1,share_ptr 是...
  • 智能指针share_ptr实现

    2019-03-18 18:33:24
    share_ptr: 可以共同指向同一个空间,采用计数表示目前有多少share_ptr指向它,当计数为0时,我们才释放这一块空间。 代码简单实现: #include<...class SharePtr { private: T *ptr...
  • new、delete初识(new、delete) new 、delete 申请的内存是在堆里面,和c语言中的malloc、free一样。是直接内存管理方式。 class A { // 称为间接内存管理 int i, j; // 临时对象 ...int *ptr2 = n

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,516
精华内容 6,606
关键字:

share_ptr