C++11智能指针详解

作用与用法

一种利用生命周期来控制程序资源的简单技术,类似于原生指针的,目的是解决异常等发生的内存安全问题。在构造对象时获取资源,对象析构时释放资源。

一般情况下,c/c++程序员担心的泄露有两种:堆泄露、系统资源泄露;

堆泄露:是指new/malloc realloc calloc  在堆上申请的内存,没有经过 new 或者free释放,导致部分空间无法在使用;

系统资源泄露:是指 程序使用系统分配的资源,比如套接字、文件描述符、管道等对应的函数,却没有正确的释放,导致系统资源的浪费。

发展史

c++98 引入auto_ptr  管理权转移,早期设计缺陷,一般情况下禁止使用

c++11引入unique_ptr 防拷贝

c++11引入shared_ptr 引用计数

c++11引入weak_ptr  循环引用 专门解决循环引用的问题 不是智能指针

template <class T>
class Smatrptr{
public:
   Smatrptr(T* ptr=nullptr):_ptr(ptr){}   //具有指针的行为,可以通过*去解引用,也可以通过->访问地址
   ~Smatrptr(){   
                if(_ptr)
               delete _ptr;
               }   
   T* operator ->(){ return _ptr;}
   T& operator *(){ return *_ptr;}
private:
 T *_ptr;
 };

auto_ptr//管理权转移 但是不能进行拷贝构造,把之前管理的对象清空,会造成之前的资源不能访问

template <class T>
class auto_ptr{

    public:
        auto_ptr(T*ptr=nullptr):_ptr(ptr){  }
        ~auto_ptr(){ if(_ptr) delete _ptr;}
         T* operator ->(){ return _ptr;}
        T& operator *(){ return *_ptr;}

//拷贝构造 一旦发生拷贝构造,将p的资源托管给当前对象中,p与其所托管的资源断开;这样就解决一块空间被
//多个对象管理,而造成程序崩溃的问题
     auto_ptr(const auto_ptr<T> &p):_ptr(p._ptr){
       p._ptr=nullptr;
   }
//赋值构造
auto_ptr& operator(auto_ptr<T>&p){
       if(p!=this){ 
         if(_ptr)
            delete _ptr;
           _ptr=p._ptr;
          p._ptr=nullptr;
          }
         return *this;
          }
private:
    T* _ptr;
        };

unique_ptr 设计非常简单粗暴, 防拷贝,也就时不能拷贝

template<class T>
class unique_ptr(){
       unique(T *ptr=nullptr):_ptr(ptr){ }
       T* operator ->(){ return _ptr;} 
       T& operator *(){ return *_ptr;}
      unique_ptr(unique_ptr<T>p)=delete;//c++11的用法
     unique_prt & opertaor= (unique_ptr<T>&p)=delete;
private:
 T * _ptr;

      }

share_prt  通过引用计数的方式来实现多个shared_ptr对象之间的共享资源

template<class T>
class shared_ptr{
   shared_ptr(T*p=nullptr):_ptr(p),_pRefcount(new int(1)),_pMutex(new mutex){}
   shared_ptr(shared_ptr<T>&p):_ptr(p._ptr),_pRefcount(p._pReefcount),_pMutex(p._pMutex){
         add();
    }
      shared_ptr<T>& operator = (shared_ptr<T>&p){ 
                  if(this!=p){
                  release();
                 _ptr=p._ptr;
                 _pRefcount=p._pRefcount;
                 _pMutex=p._pMutex;
                 add();
                  }
                 return *this;

                  }
       T* operator ->(){ return _ptr;}
      T& operator *(){ return  *_ptr;}
     void add(){ _pMutec->lock();
            
            ++(*pRefcount);
          _pMutex->unlock();
         }
private:
   void release(){
       bool deleteflae=false;
       _pMutes->lock();
     if(--(*pRefcount)==0){
        delete _ptr;
     delete _pRefcount;
     deletflag=true;
          }
       if(deleteflag) delete _pMutex;

        }
T *_ptr;
int * _pRefcount;
mutex* _pMutex;

     };  

weak_ptr 是为了解决shared_ptr循环引用的问题;

srtuct list{
int data;
list* _prev;
list* _next;
};
shared_ptr<list>node1(new list);
shared_ptr<list>node2(new list); //程序会崩溃,

srtuct list{
int data;
weak_ptr<list> _prev;
weak_ptr<list> _next;
};
shared_ptr<list>node1(new list);
shared_ptr<list>node2(new list);//这样就可以了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值