C 11智慧型指標

2022-06-05 19:36:11 字數 3144 閱讀 4741

程式使用new從堆(自由儲存區)分配記憶體,在不需要時,應使用delete將其釋放。這個記憶體管理過程由程式設計師控制,記憶體洩露是困擾c/c++程式設計師的一大難題。,c++11中引入了智慧型指標的概念,方便管理堆記憶體。使用普通指標,容易造成堆記憶體洩露(忘記釋放)、二次釋放、程式發生異常時記憶體洩露等問題等,使用智慧型指標能更好的管理堆記憶體。

在c++11中摒棄了auto_ptr(在 c++ 17 中被移除),新增三種智慧型指標:

shared_ptrunique_ptr都有乙個explicit建構函式,因此不能自動將指標轉換為智慧型指標物件,必須顯式呼叫

4.8.2

explicit shared_ptr(_tp1* __p)

: __shared_ptr<_tp>(__p)

explicit unique_ptr(pointer __p) noexcept

: _m_t(__p, deleter_type())

std::shared_ptr是通過指標保持物件共享所有權的智慧型指標。shared_ptr的目標非常簡單:多個指標可以同時指向乙個物件。下列情況之一出現時銷毀物件並解分配其記憶體:

int *p_int = new int;

shared_ptrsptr1(p); // ok

shared_ptrsptr2 = sptr1; // ok 引用計數+1

shared_ptrsptr3 = p_int; // error!!!

shared_ptrsptr1 = make_shared(100); // ok 使用 make_shared

shared_ptr預設呼叫delete釋放關聯的資源。如果使用者採用乙個不一樣的析構策略時,他可以自由指定構造這個shared_ptr的策略。如下:當離開作用域時,預設的析構函式呼叫delete釋放資源。實際上,我們應該呼叫delete來銷毀這個陣列。

class test ;

void main()

使用者可以通過呼叫乙個函式,例如乙個lamda 表示式,來指定乙個通用的釋放步驟。

shared_ptrsptr1(new test[5], [ ](test* p) );
不要用乙個原始指標初始化多個shared_ptr,否則會造成二次釋放同一記憶體。

void main()
如上,直接使用原始指標初始化多個shared_ptr,使用時,智慧型指標相互間不知道彼此的存在。p1、p2儲存在棧上,程式結束時,首先 p2 死亡時引用計數為 0 ,釋放掉 ptr 。接著 p1 死亡,p1 記錄的引用計數也為 0 。再次對物件進行釋放,crash !!!

引用計數是一種便利的記憶體管理機制,但它有乙個很大的缺點,那就是不能管理迴圈引用的物件。

class parent 

public:

shared_ptrm_child;

};class child

public:

shared_ptrm_parent;

}void main()

兩個物件的引用計數都是 2 。當p_child離開作用域時,子類物件引用計數 -1 (值為1)。當p_parent離開作用域時,父類物件引用計數 -1 (值為1)。兩個智慧型指標生命期都結束了,但是物件記憶體卻都沒得到釋放!!!

解決迴圈引用

為了解決迴圈引用c++提供了另外一種智慧型指標:weak_ptr

std::weak_ptr是一種智慧型指標,它對被std::shared_ptr管理的物件存在非擁有性(「弱」)引用。在訪問所引用的物件前必須先轉換為std::shared_ptr

強引用:被引用的物件活著,這個引用就存在。只要有乙個強引用存在,這個物件就不能被釋放。

弱引用:弱引用不修改物件的引用計數,意味這弱引用它並不對物件的記憶體進行管理,在功能上類似於普通指標,然而乙個比較大的區別是,弱引用能檢測到所管理的物件是否已經被釋放,從而避免訪問非法記憶體。

class parent 

public:

weak_ptrm_child;

};class child

public:

weak_ptrm_parent;

}

std::unique_ptr是通過指標占有並管理另一物件,並在unique_ptr離開作用域時釋放該物件的智慧型指標。

在下列兩者之一發生時用關聯的刪除器釋放物件:

unique_ptr的建立方法和shared_ptr一樣,除非建立乙個指向陣列型別的unique_ptrunique_ptr提供了建立陣列物件的特殊方法,當指標離開作用域時,呼叫delete代替delete。當建立unique_ptr時,這一組物件被視作模板引數的部分。這樣,程式設計師就不需要再提供乙個指定的析構方法

unique_ptr提供乙個release()的方法,釋放所有權。releasereset的區別在於,release僅僅釋放所有權但不釋放資源,reset釋放所有權同時也釋放資源。

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...

c 11 智慧型指標

如果在程式中使用new從堆 自由儲存區 分配記憶體,等到不需要時,應使用delete將其釋放。c 引入了智慧型指標auto ptr,以幫助自動完成這個過程。c 11摒棄了auto ptr,並新增了三種智慧型指標 unique ptr,shared ptr,weak ptr。一.auto ptr,un...

c 11 智慧型指標

首先來看shared ptr,先貼一小部分vs2013裡的實現 template class shared ptr template class shared ptr public ptr base ty template explicit shared ptr ux px template cla...