• 智能指针实现


    原来的内存管理代码

    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的区别?

     

  • 相关阅读:
    How to Create a site at the specified URL and new database (CommandLine Operation)
    Using Wppackager to Package and Deploy Web Parts for Microsoft SharePoint Products and Technologies
    SQL Server Monitor v0.5 [Free tool]
    How to build Web Part
    Deploy web part in a virtual server by developing a Web Part Package file(.cab)
    How to recreate "sites" link if you delete it accidentally
    SharePoint Portal Server管理匿名访问设置
    Monitor sql connection from .Net SqlClient Data Provider
    Brief installation instruction of Sharepoint Portal Server
    How to Use SharePoint Alternate URL Access
  • 原文地址:https://www.cnblogs.com/sofard/p/9821540.html
Copyright © 2020-2023  润新知