智能指標實現

來源:互聯網
上載者:User

標籤:try   mem   管理   nbsp   under   刪除   組元   複製構造   好的   

原來的記憶體管理代碼

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的區別?

 

 

智能指標實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.