智慧型指標 2

2021-09-08 03:16:22 字數 2943 閱讀 7368

一、指標指標能做什麼

在編寫c++程式的時候,讓我們最頭痛的問題就是記憶體洩露,也就是說:

int* pt = new int;

delete pt;

必須保證new和delete必須成對出現。作為程式設計師,我們最理想的指標,是可以像使用普通變數一樣來使用的指標,這個指標可以在恰當的時候被自動釋放。智慧型指標就是這樣的乙個指標,它的任務是要保證每乙個被動態分配的記憶體塊都能夠被釋放。

就像我們在寫handle = createsession(...);和closesession(handle);的時候,因為要保證這兩者成對出現,我們習慣的做法是將其分別放在乙個類的構造和析構函式當中。這樣,就能保證每乙個createsession都有對應的closesession了。

同樣,為了保證new和delete的成對出現,智慧型指標也採用同樣的做法——分別放在構造和析構函式中去。

class intptr 

~intptr() 

int& operator*() 

};我們可以方便的執行以下**,而不必擔心記憶體洩漏的問題:

somefunction()

以上我們給出的「智慧型指標」有個致命錯誤。設想我們執行以下**會有怎樣的情況發生:

void somefunction()

對於普通指標來說,pt2 = pt1只是讓pt2指向與pt1相同的位址,但是對於我們的智慧型指標來說,pt2原先指向的位址被洩露掉了,而pt1所指向的位址被釋放了兩次。所以,我們給每個new出來的記憶體位址對應的分配乙個「被指向計數器」,由它記錄這塊記憶體位址被多少指標所指向。

二、如何改進

於是我們得到這樣乙個「智慧型指標」,它已經可以滿足我們對intptr 型別的全部需要了:

class intptr

intptr(const intptr& rhs) // 拷貝建構函式

~intptr()

else

}intptr& operator= (const intptr& rhs)

m_p = rhs.m_p;    // 指向同一記憶體塊

m_count = rhs.m_count;  // 使用同乙個計數器

(*m_count)++;    // 計數器加

printf("new smart pointer added to current memory\n");

return *this;

}int & operator*()

};於是當我們執行以下**時,我們可以得到這樣的結果:

void somefunction()

smart pointer created.

new smart pointer added.

10smart pointer created.

original memory deleted

new smart pointer added to current memory

10smart pointer removed

smart pointer removed

smart pointer removed and memory deleted

三、一種標準的實現

namespace smart

~smart_count() {}

// 增加引用計數, 並返回計數值.

int addref()

// 減少引用計數, 並返回計數值.

int release()

private:

// 計數變數.

int use_count;

};// 智慧型指標.

template

class smart_ptr

// 構造空指標.

explicit smart_ptr () : p(null), u(null)

{}// 智慧型指標析構.

~smart_ptr (void)  }

// 智慧型指標拷貝建構函式.

smart_ptr (const smart_ptr& t)

}// 指標賦值.

void operator= (smart_ptr& t)

// 直接賦值.

p = t.p;

u = t.u;

if (u) // 必須判斷空值.

}// 過載->操作和*操作符.

t *operator-> (void)

t& operator *(void)

// 過載!操作符.

bool operator! () const

// 過載指標bool值操作符.

typedef smart_ptrthis_type;

typedef t * this_type::*unspecified_bool_type;

operator unspecified_bool_type() const

// 得到原指標.

t* get()

void reset(t* ptr)

// 賦值, 如果是null, 則不建立引用計數.

p = ptr;

if (p)

u = new smart_count(1);

else

u = null;

}void reset(smart_ptr& t)

// 賦值.

p = t.p;

u = t.u;

if (u) // 必須判斷空值.

}private:

t* p;

smart_count* u;

};// 過載==操作符.

templateinline bool operator==(smart_ptr& a, smart_ptr& b)

// 過載!=操作符.

templateinline bool operator!=(smart_ptr& a, smart_ptr& b)

}

2 智慧型指標

為什麼需要智慧型指標?乙個類庫的產生勢必有其被觸發的動機,正如某句經典語所云 在這個世界上,沒有無緣無故的愛,也沒有無緣無故的恨。同樣的,在c 世界裡,也不是無緣無故的出現智慧型指標。搞清楚智慧型指標的設計動機,對於正確的理解智慧型指標工作原理 設計思想 以及適用場合是有著非常直接的幫助。所以,讓我...

筆記 2 智慧型指標

原生指標是一款很強大的工具,但是依據進數十年的經驗,可以確定的一點是 稍有不慎,這 個工具就會反噬它的使用者。c 11標準中規定了四個智慧型指標 std auto ptr,std unique ptr,std shared ptr,std weak ptr.他們都是用來輔助管理動態分配物件的宣告週期...

智慧型指標 強弱智慧型指標

在平時編寫 的時候經常會用到new來開闢空間,而我們開闢出來的空間必須得手動去delete他,但是如果程式設計師忘記去手動釋放那邊會出現乙個麻煩的問題,記憶體洩漏!或者是一塊記憶體被多個函式同時使用時,如果其中乙個函式不知道還有其他人也在使用這塊記憶體而釋放掉的話同樣也會引起程式的崩潰。引起記憶體洩...