C++11中新增加的智慧指標
針對動態記憶體管理的問題:申請的動態記憶體中的物件該什麼時候釋放的複雜問題,比如有時忘了釋放記憶體而產生的記憶體洩露,有時在尚有指標引用記憶體的情況下就釋放了它而產生引用非法記憶體的指標。C++11中新增加了智慧指標型別來管理動態物件。它能自動釋放所指向的物件。其實,指標也是模板類,它的建構函式接管動態物件,解構函式釋放動態物件。
C++11中的智慧指標有shared_ptr、unique_ptr(auto_ptr的升級)、weak_ptr。
shared_ptr允許多個指標指向同一個物件,採用的是引用計數的方式,當一個shared_ptr型別的指標指向該物件時,引用計數加一,當不再指向該物件時,引用計數減一。用引用計數為0時,則釋放該物件。這裡要區分賦值操作和拷貝操作: shared_ptr<T> p(q); 會遞增q中的引用計數; p = q; 會遞減p的引用計數,遞增q的引用計數。
可以用make_shared<T>(arg)函式來在動態記憶體中分配一個物件並初始化它,返回一個次物件的shared_ptr。
shared_ptr<int> pi = make_shared<int>(42);
或者直接用new動態分配和初始化物件:
shared_ptr<int> pi(new int(5));
但是不能採用賦值的方式:
shared_ptr<int> pi = new int(5); //error
unique_ptr在某一時刻只能有一個該型別的指標指向動態物件。因此不能拷貝和賦值unique_ptr。要採用new直接初始話的形式:
unique_ptr<int> ui(new int(5));
weak_ptr是一種不控制所指物件生存週期的智慧指標,它指向由一個shared_ptr管理的物件。將一個weak_ptr繫結到一個shared_ptr不會改變shared_ptr的引用計數。一旦最後一個指向物件的shared_ptr被銷燬,物件就會被釋放,及時即使有weak_ptr指向物件,也還是會被銷燬的。
shared_ptr<int> p = make_shared<int>(5);
weak_ptr<int> wp(p);
為了檢查物件是否存在,必須呼叫lock函式,如果存在返回一個指向共享物件的shared_ptr,不存在返回空的shared_ptr:
if(shared_ptr<int> np = wp.lock())
{
cout<<*np<<endl;
}
智慧指標和動態陣列
對於動態陣列可以用 new int[n] 和 delete[] 操作。shared_ptr預設的操作單個物件,如果要管理動態陣列,要自己編寫刪除器:
shared_ptr<int> sp(new int[10], [](int *p) {delete[] p;});
sp.reset();
unique_ptr可以直接操作動態陣列:
unique_ptr<int []> up(new int[10]);