在C++中,智能指針是存儲一些動態分配對象或者資源的類,主要用於控制資源或者動態對象的使用生存期,設計的目的如下:
- 保證能夠正確的分配和銷毀動態對象或者資源,以防止內存洩露等問題。
- 跟蹤對象或者資源的使用情況。
智能指針的實現一般都是使用引用計數,將一個計數器與使用的指針相關聯起來,此時引用計數器跟蹤該所屬類有外部多少共享。因此在實現的時候,就有兩個根本的部分
- 計數表示。用於實現對動態對象或者資源使用的計數。
- 指針表示。用於將動態對象或者資源的指針使用間接表現。
根據智能指針主要是上面兩大部分,智能指針可以稱為“智能計數指針”,智能主要是計數的意思,當然計數的用途就因應用而不同了,或者只是為了跟蹤,或者是為了資源管理,或者是為了防止多次釋放等等。
一,智能指針實現
下面的模板類,用於實現對指針的封裝,其實現的功能如下:
- 指針構造。根據需要被封裝的動態對象或者資源的指針,構造智能指針,一般在構造時,會將資源的計數加1;
- 指針運算符重載。下面重載了*,=,->等運算符。
- 指針數據。一個指向模板類型的指針,T* ptr_
- 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的智能指針
scoped_refptr<window> win;
此時,上面的模板就會包含一個window *ptr_的指針,從上面可以看出,為了能夠正常工作,這類型的指針都必須要實現AddRef和Release方法,這應該不會是要求在class window中實現的吧?那也不太不符合封裝的正常邏輯了。答案是:當然不會在class window中實現,這兩個方法主要是針對計數的方法,專門針對class window封裝一個計數器類,下面的計數器封裝。