13.8 Write a smart pointer class. A smart pointer is a data type, usually implemented with templates, that simulates a pointer while also providing automatic garbage collection. It automatically counts the number of references to a SmartPointer<T*> object and frees the object of type T when the reference count hits zero.
這道題讓我們實現智慧指標,所謂智慧指標,就是除了具有普通指標的功能外,還能通過自動記憶體管理來提供安全性。它能避免一系列問題,如迷路指標,記憶體洩露,分配失敗等錯誤。智慧指標必須維護一個引用計數變數來統計給定物件的所有引用。實現過程主要有如下幾個部分:
- 建構函式(通過引用物件構造)
- 拷貝建構函式(通過另一個智慧指標物件構造)
- 等號過載函式
- 解構函式
- 移除引用函式
對於通過引用物件來構造的建構函式,我們需要將ref指標指向物件,然後申請一個空間給計數器,並賦值為1.
對於拷貝建構函式,我們除了要把引數中智慧指標物件中的物件指標和計數器賦值過來,計數器還要自增1,因為又多了一個物件的引用。
對於等號過載函式,我們首先判斷等號左右兩邊的智慧指標是否為同一個指標,是的話直接返回this指標即可。由於我們要覆蓋等號左邊的智慧指標,所以當其本身指著一個物件時,我們要呼叫移除引用函式,然後再賦上新的引用函式,賦值過程和上面的拷貝建構函式類似。
對於解構函式,直接呼叫移除引用函式即可。
對於移除引用函式,我們首先將計數器自減1,如果此時計數器為0了,我們要釋放物件指標和計數的記憶體,並將指標設為空指標。
參見程式碼如下:
template <class T> class SmartPointer { public: SmartPointer(T *ptr) { ref = ptr; ref_count = (unsigned*)malloc(sizeof(unsigned)); *ref_count = 1; } SmartPointer(SmartPointer<T> &sptr) { ref = sptr.ref; ref_count = sptr.ref_count; ++(*ref_count); } SmartPointer<T>& operator = (SmartPointer<T> &sptr) { if (this == &sptr) return *this; if (*ref_count > 0) remove(); ref = sptr.ref; ref_count = sptr.ref_count; ++(*ref_count); return *this; } ~SmartPointer() { remove(); } T getValue() { return *ref; } protected: T *ref; unsigned *ref_count; void remove() { --(*ref_count); if (*ref_count == 0) { delete ref; free (ref_count); ref = nullptr; ref_count = nullptr; } } };