zoukankan      html  css  js  c++  java
  • 智能指针实现

    原来的内存管理代码

    int main()
    {
    int *ptr = new(nothrow) int(0);  //关闭异常
    if(!ptr) 
    {
    cout << "new fails."
    return 0;
    }

    if(!check())  ///有校验 ,抛出异常,每次都得管理内存

    {

      delete ptr;             //释放
      ptr = nullptr;          //防止空悬指针

     throw exception();

    }
    delete ptr;             //释放
    ptr = nullptr;          //防止空悬指针
    return 0;
    }

     /////////////////////////////////////////////////////////////////////////////////////////////////

    使用引用计数,实现智能指针

    1.构造函数中计数初始化为1,拷贝构造函数中计数值加1;

    2.析构函数中引用计数减一;

    3.赋值运算符中,左边的对象引用计数减一,右边的对象引用计数加一;

    4.在赋值运算符和析构函数中,如果减一后为0,则调用delete释放对象。

    /////////////////////////////////////////////////////////////////////////////////////////////

    智能指针即为封装好的,带计数的指针,需要实现 构造函数,拷贝构造,赋值构造,析构

    #include <iostream>
    using namespace std;

    template<class T>  //模板类T,智能指针即为封装好的,带计数的指针
    class SmartPtr
    {
      public:
      SmartPtr(T *p); //构造函数,参数是普通指针

           SmartPtr(const SmartPtr<T> &orig); // 拷贝构造  ,浅拷贝
      SmartPtr<T>& operator=(const SmartPtr<T> &rhs); // 赋值操作符号,浅拷贝
      ~SmartPtr()    ; //析构函数
      
      private:
      T * ptr;  // 指针
      int *use_count; // 将use_count声明成指针是为了方便对其的递增或递减操作
    };

    template<class T>
    SmartPtr<T>::SmartPtr(T *p) : ptr(p)
    {
      try
      {
        use_count = new int(1);   //分配计数内存
      }
      catch (...)
      {
      delete ptr;
      ptr = nullptr;
      use_count = nullptr;
      cout << "Allocate memory for use_count fails." << endl;
      exit(1);  //退出程序
      }

      cout << "Constructor is called!" << endl;
    }

    template<class T>
    SmartPtr<T>::~SmartPtr()
    {
      // 只在最后一个对象引用ptr时才释放内存
      if (--(*use_count) == 0)
      {
      delete ptr;
      delete use_count;
      ptr = nullptr;
      use_count = nullptr;
      cout << "Destructor is called!" << endl;
      }
    }

    template<class T>
    SmartPtr<T>::SmartPtr( const SmartPtr<T> &orig)
    {
      ptr = orig.ptr;
      use_count = orig.use_count;
      ++(*use_count);
      cout << "Copy constructor is called!" << endl;
    }

    // 重载等号函数不同于复制构造函数,即等号左边的对象可能已经指向某块内存。
    // 这样,我们就得先判断左边对象指向的内存已经被引用的次数。如果次数为1,
    // 表明我们可以释放这块内存;反之则不释放,由其他对象来释放。
    template<class T>
    SmartPtr<T>&   SmartPtr<T>::operator  =  (const SmartPtr<T> &rhs)
    {
           //这句话如果放在最后面,那么 rhs=rhs(计数为1的时候),将会释放内存
          ++(*rhs.use_count);

      // 将左操作数对象的使用计数减1,若该对象的使用计数减至0,则删除该对象
           if (--(*use_count) == 0)
      {
        delete ptr;
        delete use_count;
        cout << "Left side object is deleted!" << endl;
      }

      ptr = rhs.ptr;
      use_count = rhs.use_count;

      cout << "Assignment operator overloaded is called!" << endl;
      return *this;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    使用方法

    指向单个元素的  智能指针,会有默认内存释放器,也可自己定义

    shared_ptr<string> str_point  ( new string("jutta"),
      // 自定义析构函数,lamada表达式
      [](string *p)
      {
      cout << "delete " << *p << endl;
      delete p;
      }
      );

    指向数组元素的  智能指针,需要自己定义内存释放函数

    shared_ptr<int>  int_point  ( new int[10],
      // 自定义析构函数,lamada表达式
      [](int *p)
      {
      delete[] p;
      }
      );

    也可以使用unique_ptr的default_delete函数

    shared_ptr<int>  int_point  (new int[10], default_delete <int [] > () );

    share_prt与weak_ptr的区别?

     

  • 相关阅读:
    paper 66: MATLAB函数—disp的使用
    paper 65 :尺度不变特征变换匹配算法[转载]
    paper 64:尺度空间(Scale space)理论
    paper 63 :函数比较:imfilter与fspecial
    paper 62:高斯混合模型(GMM)参数优化及实现
    paper 61:计算机视觉领域的一些牛人博客,超有实力的研究机构等的网站链接
    paper 60 :转载关于视觉SCI期刊
    paper 59:招聘
    paper 58 :机器视觉学习笔记(1)——OpenCV配置
    paper 57 :颜色直方图的代码
  • 原文地址:https://www.cnblogs.com/sofard/p/9821540.html
Copyright © 2011-2022 走看看