智慧型指標是c++中為了實現資源的有效管理而被提出的,我們可以建立它但無須操心它的釋放問題,在引入異常機制的程式裡它是十分有用的,或者說,對於博主這中粗心大意的人來說還是可以偶爾使用的。他可以在一些場合防止記憶體洩漏的問題。但是,智慧型指標也是存在著許多的問題,所以許多的程式設計規範裡告誡我們少使用智慧型指標,但對於我們來說,必須了解它的原理。
*raii:資源獲得即初始化,我們在建構函式裡將其初始化,並在析構函式裡釋放它
eg:乙個簡單的autoptr的實現
templateclass autoptr
public:
autoptr(t * p) :_ptr(p)
{} autoptr(autoptr & ap)
autoptr& operator =(autoptr & ap)
return *this;
} t& operator *()
t* operator ->()
~autoptr() }
private:
t* _ptr;
};
我們可以看出,上面的程式問題在**呢,我們力求來模仿原生指標讓多個autoptr管理同一塊空間但是更加嚴重的問題出現:我們將管理許可權僅交給最後乙個autoptr,但是如果有的客戶程式設計師們不了解這個機制而將其當做普通的指標來使用,如果他使用了沒有管理許可權的指標將發生錯誤!
為了避免這樣的錯誤出現,我們使用了一種簡單暴力的方拷貝機制處理從而使得scopedptr粗線啦
templateclass scopedptr
~scopedptr()
t& operator *()
t* operator ->()
private:
t* _ptr;
scopedptr(scopedptr& sp);
scopedptr& operator =(scopedptr& sp);
};
為了避免這種錯誤發現,我們可以直接拒絕客戶程式設計師做拷貝構造和賦值操作,使得我們的程式變得更加安全,遺憾的是,這樣我們的指標就不能做到和原生指標一樣可以使用多個指標共同維護一塊空間了。
*防拷貝的實現:把拷貝構造及賦值運算子的過載宣告成私有/保護成員,並且只宣告不定義。
然而這樣的智慧型指標似乎還是不太理想。所以我們又發現,可以使用引用計數的方法使得我們的指標能更加像原生指標的行為,於是,我們的sharedptr出現
template class sharedptr
sharedptr(sharedptr& sp)
sharedptr& operator=(sharedptr sp)
t* operator ->()
t& operator *()
~sharedptr() }
int getcount()
private:
t * _ptr;
int *_pcount;
};
(以上**為現**法,如果這個時候你還是挺閒的就別忘記把傳統寫法也實現下啵
)是不是覺得有點贊,不得不說,想出這些方法的大大們還是棒棒的。
其實,我們首先介紹的autoptr的實現方法還有另一種,不過現在大家已經基本拋棄了這種寫法。
eg:autoptr實現方法二
#include//*************autoptrwithowner***********
templateclass autoptrwithowner
scopedptrwithowner(autoptrwithowner& sp)
autoptrwithowner& operator=(autoptrwithowner& sp)
else if (_ptr != sp._ptr)
return *this;
} ~autoptrwithowner()
private:
t *_ptr;
bool _owner;
};
相比於我們介紹的第一種方式,似乎這種方式的安全性並不高,它和產生垂懸指標哦,就是我們所說的野指標。所以請你盡量不要使用這種方式。
我們看到上面的例子中已經介紹了三種智慧型指標
那麼博主都認識哪些智慧型指標呢?
1.auto ptr 實現:管理許可權的轉移
2.shared ptr 實現:引用計數
3.scoped ptr 實現:防止拷貝
4.weak ptr (弱指標,用於輔助shared ptr)
實際上shared ptr仍然存在許多的缺陷,它可能引入:執行緒安全問題,迴圈引用問題,刪除器不匹配
*執行緒安全:
今天我們主要為大家解決後兩個問題(其實是因為博主還沒有學習多執行緒程式設計,不會啦,夭壽啊!
)1.定製刪除器(使用模板實現)
#include#define _crt_secure_no_warnings 1
//**************定製刪除器的實現***********
template>
class sharedptr
*/ sharedptr(t *ptr) :_ptr(ptr), _pcount(new int(1))
{} sharedptr(const sharedptr& sp)
sharedptr& operator =(sharedptr sp)
~sharedptr()
private:
t *_ptr;
t *_pcount;
del _del;
void _relese() }
};template struct free
};template struct delete
};template struct fclose
};void testshareptrdelete()
void testshareptrfree()
void testshareptrfclose()
*仿函式
:使用operator()使得物件方法的呼叫形式像一般的函式一樣
2.迴圈引用
什麼是迴圈引用嘞?我們來舉栗子好了
struct node
~node()
上面的程式就出現了迴圈引用的問題我們可以看見我們呼叫之後並沒有呼叫析構函式,這樣就引起了記憶體洩漏的問題,為什麼呢,因為其每乙個節點一開始被乙個shared_ptr指著,後來你在例項化之後因為他又被他前面或者後面的節點所指,引用計數發生了增加,所以在析構的時候檢查到自己的引用計數沒有減到0所以沒有釋放本來該釋放的空間。
其實這個問題是很好解決的,我們將node裡面的shared_ptr換成weak_ptr就可以完美解決,在此處,weak_ptr輔助了shared_ptr而沒有增加引用計數~
博主要去了解尾大的民間組織寫出的boost庫辣~\(≧▽≦)/~
本文出自 「zimomo」 部落格,請務必保留此出處
C 的RAII和智慧型指標小結
raii 資源分配即初始化,利用建構函式和析構函式定義乙個類來完成對資源的分配和釋放 智慧型指標主要用來防止記憶體洩漏,我們來舉個栗子,看看為什麼會有智慧型指標這個東東 例1 對於上面這段程式,由於丟擲異常的時候影響了 的執行流,所以要在異常捕獲之前將p提前釋放 詳見 我的部落格 c 的異常 雖然可...
兩種智慧型指標 RAII智慧型指標和引用計數智慧型指標
raii的全稱是 resource acquisition is initialization 也就是 資源獲取就是初始化 就像記憶體分配是在變數初始化的時候分配的 比如,當程式結束時,系統會自動釋放程式所使用的資源 函式傳值時,當函式呼叫結束,該值也將消亡。include define safe ...
智慧型指標 強弱智慧型指標
在平時編寫 的時候經常會用到new來開闢空間,而我們開闢出來的空間必須得手動去delete他,但是如果程式設計師忘記去手動釋放那邊會出現乙個麻煩的問題,記憶體洩漏!或者是一塊記憶體被多個函式同時使用時,如果其中乙個函式不知道還有其他人也在使用這塊記憶體而釋放掉的話同樣也會引起程式的崩潰。引起記憶體洩...