智慧型指標是基於raii機制實現的類(模板),具有指標的行為(過載了operator*與operator->操作符),可以「智慧型」地銷毀其所指物件。c++11中有unique_ptr、shared_ptr與weak_ptr等智慧型指標,可以對動態資源進行管理
unique_ptr「唯一」擁有其所指物件,同一時刻只能有乙個unique_ptr指向給定物件(通過禁止拷貝語義、只有移動語義來實現)。
unique_ptr指標本身的生命週期:從unique_ptr指標建立時開始,直到離開作用域。離開作用域時,若其指向物件,則將其所指物件銷毀(預設使用delete操作符,使用者可指定其他操作)。
unique_ptr指標與其所指物件的關係:在智慧型指標生命週期內,可以改變智慧型指標所指物件,如建立智慧型指標時通過建構函式指定、通過reset方法重新指定、通過release方法釋放所有權、通過移動語義轉移所有權。
[cpp]view plain
copy
//智慧型指標的建立
unique_ptr> u_i;
//建立「
空智能指標」
u_i.reset(new
int(3));
//"繫結」動態物件
unique_ptr> u_i2(
newint
(4));
//建立時指定動態物件
//所有權的變化
int*p_i = u_i2.release();
//釋放所有權
unique_ptru_s(new
string(
"abc"
));
unique_ptru_s2 = std::move(u_s); //所有權轉移(通過移動語義),u_s所有權轉移後,變成「空指標」
u_s2=nullptr;//顯式銷毀所指物件,同時智慧型指標變為空指標。與u_s2.reset()等價
(1) 動態資源的異常安全保證(利用其raii特性):
[cpp]view plain
copy
void
foo()
[cpp]view plain
copy
void
foo()
(2) 返回函式內建立的動態資源
[cpp]view plain
copy
unique_ptrfoo()
(3) 可放在容器中(彌補了auto_ptr不能作為容器元素的缺點)
方式一:
[cpp]view plain
copy
vector> vs ,
newstring };
方式二:
[cpp]view plain
copy
vector>v;
unique_ptrp1(new
string(
"abc"
));
v.push_back(std::move(p1));//這裡需要顯式的移動語義,因為unique_ptr並無copy語義
(4) 管理動態陣列,因為unique_ptr有unique_ptr過載版本,銷毀動態物件時呼叫delete
[cpp]view plain
copy
unique_ptr<
int> p (
newint
[3]);
p[0] = 0;// 過載了operator
unique_ptr預設的資源刪除操作是delete/delete,若需要,可以進行自定義:
[cpp]view plain
copy
void
end_connection(connection *p)
//資源清理函式
unique_ptr//資源清理器的「型別」
p(&c, end_connection);// 傳入函式名,會自動轉換為函式指標
在c++11環境下,auto_ptr被看做「遺留的」,他們有如下區別:
auto_ptr有拷貝語義,拷貝後源物件變得無效;unique_ptr則無拷貝語義,但提供了移動語義
auto_ptr不可作為容器元素,unique_ptr可以作為容器元素
auto_ptr不可指向動態陣列(儘管不會報錯,但不會表現出正確行為),unique_ptr可以指向動態陣列
C 11之智慧型指標
c 98提供了了智慧型指標auto ptr,但c 11已將其摒棄,並提供了unique ptr和shared ptr。這三種智慧型指標模板都定義了類似指標的物件,可以將new獲得的位址賦給這種物件。當智慧型指標過期時,這些記憶體將自動被釋放。其基本用法如下 include include inclu...
c 11之智慧型指標
由於在c 中我們可以動態分配記憶體,但有時候我們會忘記用 delete或free釋放記憶體,就會導致記憶體洩露。所以c 11提供了智慧型指標這種東西 本文參考了知乎某知乎友的 比如下面這兩種情況 1 記憶體洩漏 str1所指的資源沒有被釋放 2 多重釋放,引起程式崩潰 可能平時都寫在乙個檔案不會忘記...
C 11智慧型指標
本文介紹c 的四種智慧型指標,其中後三種是c 11新增加的,auto ptr已被棄用。要編譯c 11,需要安裝g 4.8 sudo add apt repository ppa ubuntu toolchain r test sudo apt get update sudo apt get inst...