最近在自己寫智慧型指標的時候,遇到了一些小的疑惑,也糾正了之前的一些理解上的偏差。
首先是最簡單的智慧型指標的乙個實現:
templateclass smartpointer //建構函式
t& operator*()
t* operator->()
~smartpointer()
};
這與auto_ptr類似,可以完成自動釋放記憶體的功能,但一旦程式設計師使用了如下的方式:
class a{};
smartpointerptr(new a);
smartpointerptr1=ptr;
會導致程式崩潰,因為ptr和ptr1兩個智慧型指標會重複delete源指標,所以stl裡有了shared_ptr。
下面看一下加入了引用計數的智慧型指標的實現:
templateclass sharedpointer
sharedpointer(const sharedpointer& orig):ptr(orig.ptr),count(orig.count)
sharedpointer& operator=(const sharedpointer& rhs)
ptr = rhs.ptr;
count = rhs.count;
return *this;
} ~sharedpointer()
t& operator*()
t* operator->()
t* getoriptr()
private:
t *ptr;
size_t* count;
};
在sharedpointer裡新增了乙個指向計數的指標count,每當智慧型指標被複製構造或者賦值構造的時候,count指向的值都會自增,當count指向的值為0時,智慧型指標的析構函式才會呼叫delete釋放原始指標的記憶體。
這裡發現了兩種可能導致誤用的例子,是我在實際實用中發生的。
1.讓智慧型指標指向棧區:
class a{};
a a;
sharedpointerptr(&a);
這樣的使用,編譯器將不會報錯,但是由於a是儲存在棧區的物件,在程序結束前將自動呼叫析構函式,而我們的智慧型指標ptr會對棧區使用delete,導致程式崩潰。
2.用同乙個源指標構造兩個不同的智慧型指標:
class a{};
a* p=new a;
sharedpointerptr(p);
sharedpointerptr1(p);
這樣的使用,將導致指標p被兩次呼叫delete;原因是count指向的記憶體是在建構函式中分配的,ptr和ptr1都是通過建構函式構造出來的,其count分別指向兩個不同位址,其值都為1,在ptr析構時,ptr的count指向的值變為0,發生delete p;接下來在ptr1析構時,ptr1的count指向的值變為0,再發生delete p;這樣就導致了程式崩潰。
所以在使用智慧型指標時,應該統一採用如下使用方式:
class a{};
sharedpointerptr(new a);
sharedpointerptr1(new a);
這樣就可以保證不會出現如上兩種錯誤。 兩種智慧型指標 RAII智慧型指標和引用計數智慧型指標
raii的全稱是 resource acquisition is initialization 也就是 資源獲取就是初始化 就像記憶體分配是在變數初始化的時候分配的 比如,當程式結束時,系統會自動釋放程式所使用的資源 函式傳值時,當函式呼叫結束,該值也將消亡。include define safe ...
智慧型指標的簡單實現
智慧型指標 它的一種通用實現方法是採用引用計數的方法。智慧型指標將乙個計數器與類指向的物件相關聯,引用計數跟蹤共有多少個類物件共享同一指標。有兩種實現方法,本例簡單的實現了智慧型指標。include include using namespace std template class smartpt...
智慧型指標的簡單實現
智慧型指標 動態的管理開闢的記憶體,防止人為的記憶體洩漏。sharedptr的實現 原理 使用引用計數的原理使多個物件可以指向一塊空間。define crt secure no warnings includeusing namespace std template class sharedptr ...