shared_pointer

  1. 传统指针的问题
  2. 智能指针引用计数的原理分析
  3. 实现细节
    1. 类内细节
      1. 数据成员
      2. 核心函数
      3. 引用计数变换的情况
  4. 智能指针实现

智能指针引用计数的原理分析

  • 当利用智能指针托管从堆上申请的资源的时候,使智能指针指向这个内存,并再申请一个用于计数的资源,用于管理引用该资源的次数

实现细节

  • 智能指针是一个类,使用RAII思想,在构造函数里面申请资源,在析构函数中回收资源。在智能指针中主要就是对申请资源和引用计数是维护
  • 需要进行运算符重载,让智能指针使用起来像普通指针一下
    • 注意->重载会传递
  • 智能指针对任何类型都可以使用,所以它应该是一个模板

    类内细节

    数据成员

  • 为了管理资源,所以需要2个数据成员,引用计数是指针的形式,这可以让所有引用该资源的智能指针共享
    • T * m_pointer:原始指针
    • int* m_refCount:引用计数

      核心函数

  • addReference():当为nullpter时,创建引用计数资源,并初始化为1;否则,引用计数加1。

    void addReference()
    {
      if (m_refCount)
      {
          (*m_refCount)++;
      }
      else
      {
          m_refCount = new int(0);
          *m_refCount = 1;
      }
    }
    
  • void removeReference():引用计数减一,当变为0时,释放所有资源

      void removeReference()
      {
          if (m_refCount)
          {
              (*m_refCount)--;
              if (*m_refCount == 0)
              {
                  delete m_refCount;
                  delete m_pointer;
                  m_refCount = 0;
                  m_pointer = 0;
              }
          }
      }
    

    引用计数变换的情况

    | 构造函数| 拷贝构造函数 |拷贝赋值函数| 析构
    |—-|—-|—-|—-
    | 托管资源 | 托管资源 | 左值removeRerence | removeRerence|
    | addReference | 托管引用计数 | 托管资源 ||
    | | addReference | 托管引用计数 ||
    | | | addReference| |

智能指针实现

#include <iostream>
using namespace std;

template<typename T>
class shared_Ptr
{
public:
    shared_ptr():m_pointer(nullptr),m_refCount(nullptr){}
    shared_Ptr(T* adpotTarget):m_pointer(adoptTarget){addReference();}
    shared_Ptr(const shared_Ptr<T>& copy):m_pointer(copy.m_pointer),m_refCount(copy.m_refCount){addReference();}
    shared_Ptr<T>& operator=(const shared_Ptr<T>& that)
    {
        if(this != &that)
        {
            removeRefrence();
            m_pointer = that.m_pointer;
            m_refCount = that.m_refCount;
            addReference();
        }
        return *this;
    }

    shared_Ptr(const shared_Ptr<T>&& copy):m_pointer(copy.m_pointer),m_refCount(copy.m_refCount){copy = nullptr}
    shared_Ptr<T>& operator=(const shared_Ptr<T>&& that)
    {
        if(this != &that)
        {
            m_pointer = that.m_pointer;
            m_refCount = that.m_refCount;
            that = nullptr;
        }
        return *this;
    }

    ~shared_Ptr(){removeRefrence();}

    bool operator==(const shared_Ptr<T>& that)
    {
        return this->m_pointer == that.m_pointer;
    }

    bool operator!=(const shared_Ptr<T>& that)
    {
        return this->m_pointer != that.m_pointer;
    }

    T& operator*() const
    {
        return *m_pointer;
    }

    T* operator->() const
    {
        return m_pointer;
    }

    int getReferenceCount()
    {
        if(m_reference)
            return *m_refCount;
        else
            return -1;
    }



protected:
    void addReference()
    {
        if(!m_refCount)
        {
            m_refCount = (size_t*)malloc(sizeof(size_t));
            m_refCount = 0;
        }
        (*m_refCount)++;
    }

    void removeRefrence()
    {
        if(!m_refCount) return;
        (*m_refCount)--;
        if((*m_refCount) == 0)
        {
            delete m_pointer;
            delete m_refCount;
            m_pointer = nullptr;
            m_reference = nullptr;
        }
    }
private:
    T* m_pointer;
    size_t* m_refCount;
};