智慧型指標的簡單實現及兩種誤用方式

2021-07-11 09:52:18 字數 1696 閱讀 5395

最近在自己寫智慧型指標的時候,遇到了一些小的疑惑,也糾正了之前的一些理解上的偏差。

首先是最簡單的智慧型指標的乙個實現:

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 ...