程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 一個C++中智能指針的設計

一個C++中智能指針的設計

編輯:C++入門知識

在C++中,智能指針是存儲一些動態分配對象或者資源的類,主要用於控制資源或者動態對象的使用生存期,設計的目的如下:

保證能夠正確的分配和銷毀動態對象或者資源,以防止內存洩露等問題。
跟蹤對象或者資源的使用情況。
智能指針的實現一般都是使用引用計數,將一個計數器與使用的指針相關聯起來,此時引用計數器跟蹤該所屬類有外部多少共享。因此在實現的時候,就有兩個根本的部分
計數表示。用於實現對動態對象或者資源使用的計數。
指針表示。用於將動態對象或者資源的指針使用間接表現。
根據智能指針主要是上面兩大部分,智能指針可以稱為“智能計數指針”,智能主要是計數的意思,當然計數的用途就因應用而不同了,或者只是為了跟蹤,或者是為了資源管理,或者是為了防止多次釋放等等。
一,智能指針實現
下面的模板類,用於實現對指針的封裝,其實現的功能如下:
指針構造。根據需要被封裝的動態對象或者資源的指針,構造智能指針,一般在構造時,會將資源的計數加1;
指針運算符重載。下面重載了*,=,->等運算符。
指針數據。一個指向模板類型的指針,T* ptr_
[cpp] 
template <class T> 
class scoped_refptr { 
 public: 
  scoped_refptr() : ptr_(NULL) { 
  } 
 
  scoped_refptr(T* p) : ptr_(p) { 
    if (ptr_) 
      ptr_->AddRef(); 
  } 
 
  scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) { 
    if (ptr_) 
      ptr_->AddRef(); 
  } 
 
  template <typename U> 
  scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) { 
    if (ptr_) 
      ptr_->AddRef(); 
  } 
 
  ~scoped_refptr() { 
    if (ptr_) 
      ptr_->Release(); 
  } 
 
  T* get() const { return ptr_; } 
  operator T*() const { return ptr_; } 
  T* operator->() const { return ptr_; } 
 
  T* release() { 
    T* retVal = ptr_; 
    ptr_ = NULL; 
    return retVal; 
  } 
 
  scoped_refptr<T>& operator=(T* p) { 
    // AddRef first so that self assignment should work 
    if (p) 
      p->AddRef(); 
    if (ptr_ ) 
      ptr_ ->Release(); 
    ptr_ = p; 
    return *this; 
  } 
 
  scoped_refptr<T>& operator=(const scoped_refptr<T>& r) { 
    return *this = r.ptr_; 
  } 
 
  template <typename U> 
  scoped_refptr<T>& operator=(const scoped_refptr<U>& r) { 
    return *this = r.get(); 
  } 
 
  void swap(T** pp) { 
    T* p = ptr_; 
    ptr_ = *pp; 
    *pp = p; 
  } 
 
  void swap(scoped_refptr<T>& r) { 
    swap(&r.ptr_); 
  } 
 
 protected: 
  T* ptr_; 
}; 
有了這個類之後,我們可以定義一個指針,如針對class window的智能指針
[cpp] 
scoped_refptr<window> win; 
此時,上面的模板就會包含一個window *ptr_的指針,從上面可以看出,為了能夠正常工作,這類型的指針都必須要實現AddRef和Release方法,這應該不會是要求在class window中實現的吧?那也不太不符合封裝的正常邏輯了。答案是:當然不會在class window中實現,這兩個方法主要是針對計數的方法,專門針對class window封裝一個計數器類,下面的計數器封裝

二,計數器的封裝
這個類很簡單,有三個地方需要注意
類從模板類型繼承,就是從T繼承。上面的class window的話,就是RefCountedObject是window的派生類。
封裝計數器ref_count_。需要注意的是,對計數器的加減操作應該盡可能的保持原子性。
計數器類提供多個構造函數,都是對傳入的類型T的多種構造支持。
[cpp] 
template <class T> 
class RefCountedObject : public T { 
 public: 
  RefCountedObject() : ref_count_(0) { 
  } 
 
  template<typename P> 
  explicit RefCountedObject(P p) : T(p), ref_count_(0) { 
  } 
 
  template<typename P1, typename P2> 
  RefCountedObject(P1 p1, P2 p2) : T(p1, p2), ref_count_(0) { 
  } 
 
  template<typename P1, typename P2, typename P3> 
  RefCountedObject(P1 p1, P2 p2, P3 p3) : T(p1, p2, p3), ref_count_(0) { 
  } 
 
  template<typename P1, typename P2, typename P3, typename P4> 
  RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4) 
      : T(p1, p2, p3, p4), ref_count_(0) { 
  } 
 
  template<typename P1, typename P2, typename P3, typename P4, typename P5> 
  RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) 
      : T(p1, p2, p3, p4, p5), ref_count_(0) { 
  } 
 
  virtual ~RefCountedObject() { 
  } 
 
  virtual int AddRef() { 
    return Increment(&ref_count_); 
  } 
 
  virtual int Release() { 
    int count = Decrement(&ref_count_); 
    if (!count) { 
      delete this; 
    } 
    return count; 
  } 
 
 protected: 
  int ref_count_; 
}; 

三,實例
[cpp]
scoped_refptr<Window> win(new RefCountedObject<Window>(&client, &wnd)); 
上面的實例定義了一個智能指針win,式中client和wnd為其它參數,與定義無關。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved