c++ 98的 std::auto_ptr已經被徹底遺棄了,取而代之的是unique_ptr、shared_ptr與weak_ptr。大部分時候我們自己手動申請記憶體方式記憶體都是沒有問題的,問題是如果程式很大了之後,乙個複雜的物件,多次拷貝的代價非常高,很多地方都會使用到,只存在乙份拷貝顯然是最好的,這個時候物件生命週期的管理就會很複雜,所以c++引入了智慧型指標。
任何事物都會有兩面性。
shared_ptr
摘錄於effective c++, 3rd edition, item 17: 在 standalone statements(獨立語句)中將 new 出來的 objects(物件)存入 smart pointers(智慧型指標)比如
複製**
class widget
;~widget()
;};
int priority()
void processwidget(int priority,std::shared_ptr pw)
int main()
複製**
processwidget執行的過程應該是
1. new widget
2. shared_ptr constructor
3. priority()
我在llvm上測試的結果也是這個執行順序
也許某些編譯器上可能執行的順序是
new widget
priority() //發生異常
shared_ptr constructor
就有可能有記憶體洩露
所以最好的辦法還是應該把new widget提到外面來寫,所以好的編碼習慣很重要。
2.迴圈引用
複製**
#include
using namespace std;
class a;
class b;
typedef std::shared_ptr aptr;
typedef std::shared_ptrbptr;
class a };
class b };
int main ()
複製**
要解決這個問題就需要引入乙個弱引用的智慧型指標了weak_ptr
複製**
class a;
class b;
typedef std::shared_ptr aptr;
typedef std::shared_ptrbptr;
typedef std::weak_ptr aweakptr;
typedef std::weak_ptrbweakptr;
class a
}; class b
}; int main ()
複製**
這兩種指標其實和oc裡面的 strong, weak非常相識。
weak_ptr的另外一種用法
使用情景:當類物件被 shared_ptr 管理時,需要在類自己定義的函式裡把當前類物件作為引數傳給其他函式時,這時需要傳遞乙個 shared_ptr ,否則就不能保持 shared_ptr 管理這個類物件的語義(因為有乙個 raw pointer 指向這個類物件,而 shared_ptr 對類物件的這個引用沒有計數,很有可能 shared_ptr 已經把類物件資源釋放了,而那個呼叫函式還在使用類物件——顯然,這肯定會產生錯誤)。《摘錄:
直接看官網的例子吧:
《 複製**
#include
#include
struct good: std::enable_shared_from_this};
struct bad
~bad() };
class cobj: public std::enable_shared_from_this // 只有cobjmgr可以建立與刪除
~cobj(){}};
int main()
// ub: double-delete of bad
複製**
1.絕對不能在建構函式中呼叫shared_from_this()
因為shared_ptr裡面初始化enable_shared_from_this的成員weak_ptr, 這個時候weak_ptr還是空值。
2.為什麼內部不能用this指標
因為我們程式中用shared_ptr來管理指標,如果我們在類的內部傳遞的過程中用原始指標,這樣類內部的引用shared_ptr不會察覺到,因為有可能我們傳進去的時候已經被shared_ptr釋放掉了。
unique_ptr
相對就要單純許多了,unique_ptr「唯一」擁有其所指物件,只能有乙個unique_ptr指向給定物件(通過禁止拷貝語義、只有移動語義來實現)。
代替普通指標
複製**
void foo()
unique_ptr px(new x);
複製**
在函式中返回物件
unique_ptr foo()
放入容器中
vector> vs , new string,new string };
vector>v;
unique_ptr test(new string("11111"));
v.push_back(std::move(test));//使用移動語法
支援直接持有陣列
std::shared_ptr p(new int[10],
(int* p));
//或者使用helper
std::shared_ptr p(new int[10],std::default_delete());
C 11學習筆記 Type Support
其實主要還是對c 的std庫的學習吧,雖然用的不少但是對c 的全貌還不太了解。主要包括3個部分 基本型別 rtti 萃取技術 traits size t 用的太多了,不說了。ptrdiff t 乙個有符號的型別,通常用來表示兩個指標相減的結果,是乙個機器相關的型別。和size t不同的是,size ...
C 11學習筆記 五
指標空值 nullptr include using namespace std void f char c void f int i int main 本程式中,null被定義為0,這裡引發錯誤的原因是 c 98中,0既可以是乙個整形,也可以是乙個 void 指標。如果想要呼叫f char c 版...
C 11學習筆記二
用處 基類擁有眾多建構函式而派生類只有一些成員函式 資料不多 時,可以直接繼承基類建構函式而不必重寫。用法 class base class derive base 注意 如果派生類有多個基類時有可能導致衝突,解決辦法是派生類顯示定義該建構函式 用處 一些建構函式需要呼叫相同的 類似的 段時,可將該...