智能指针(续)

来源:互联网 发布:centos鼠标键盘动不了 编辑:程序博客网 时间:2024/06/07 01:42

一. 存在问题

上文到第三种智能指针shareptr,但是此指针也存在很多的问题

  • 若传入文件类型指针FILE *,则delete不能释放;
  • 引用计数的处理不是线程安全的
  • 循环引用问题

二.解决方法

  • 若传入文件类型指针FILE *,则delete不能释放;
    • 解决方法:特化
class Fclose{public:     void operator()(FILE* fp)    {        if(fp)           fclose(fp);    }};template <class T>class Delete{public:     void operator()(T*p)     {          if(p)             delete p;     }}template <class T>class Free{public:     void operator()(T*p)     {          if(p)             free p;     }}template <class T,class Del= Delete<T>>class SharePtr{     //构造函数同上     //拷贝构造函数同上     SharedPtr<T>& operator=(SharedPtr<T> sp)      {          if(this!= &sp)        {            Release();            _ptr = sp._ptr;            _pCount = sp._pCount;            ++(*_pCount);        }        return *this;      }      ~SharedPtr()      {          cout << "~SharedPtr()" << endl;          Release();    }  private:     void Release()     {          if(_ptr && 0==--(*pCount))          {              Del()(_ptr);              _ptr = NULL;              delete _pCount;              _pCount = NULL;          }     }};
  • 引用计数的处理不是线程安全的
#include<memory>template<class T>struct Node{   Node(const T&data)      :_next(NULL)      ,_pre(NULL)      ,_data(data)      {           cout<<"Node()"<<endl;      }       ~Node()       {            cout<<"~Node()"<<endl;       }share_ptr<Node<T>> _next;//以前_next交给一个原生态指针管理,现在交给share_ptr管理share_ptr<Node<T>> _ptr;T _data;};void Test(){   share_ptr<Node<T>> p1(new Node<int>(1));   share_ptr<Node<T>> p2(new Node<int>(1));   cout<<p1.use_count()<<endl;   cout<<p2.use_count()<<endl;   p1->_next = p2;   p2->_pre  = p1;   cout<<p1.use_count()<<endl;   cout<<p2.use_count()<<endl;}

打印结果为
Node()
Node()
1
1
2
2

问题
以上打印结果可知,并没有调用析构函数,故会造成内存泄漏
这里写图片描述

循环引用:针对那些两个指针的节点,可以引发引用循环的问题

  • 循环引用问题
struct Node{   Node(const T&data)        :_data(data)   {}   weak_ptr<Node<T>> _next;//weak_ptr依附于share_ptr,不能单独使用;   weak_ptr<Node<T>> _pre;}