C++基礎回顧4——智慧指標shared_ptr
———-引入智慧指標的目的,個人;理解有如下兩點:
1.自動釋放記憶體:智慧指標類能記錄多少個shared_ptr指向相同的物件,並在引用計數值為0時自動釋放物件所佔用的記憶體。
2.記憶體共享:讓多個物件共享底層資料。
C++動態記憶體(malloc & free, new & delete)
程式使用動態記憶體出於以下三種原因之一:
- 程式不知道自己需要使用多少物件
- 程式不知道所需物件的準確型別
- 程式需要在多個物件間共享資料
vector<string> v1;
{//新作用域
string str[] = {"a", "an", "the"};
int size = sizeof(str) / sizeof(str[0]);
vector<string> v2(str, str + size);
v1 = v2;
}//v2被銷燬,v1中包含三個元素
當拷貝一份vector時,原vector和副本vector中元素是相互分離的。
一般而言,如果兩個物件共享底層的資料,當某個物件被銷燬時,我們不能當方面的銷燬底層資料。
Blob<string> b1;
{//新作用域
Blob<string> b2 = {"a", "an", "the"};
b1 = b2;//b1和b2共享相同的元素
}
物件b1與b2具有引用相同的底層元素。
實現Blob類如下:
class strBlob
{
public:
typedef std::vector<string>::size_type size_type;
strBlob();
strBlob(initializer_list<string> i1);
size_type size() const { return data->size(); };
bool empty() const{ return data->empty(); };
//新增和刪除元素
void push_back(const string &t) {data->push_back(t); };
void pop_back();
private:
shared_ptr<vector<string>> data;
void check(size_type i, const string &msg) const;
}
shared_ptr與new的結合使用
預設情況下,一個用來初始化智慧指標的普通指標必須指向動態記憶體,因為智慧指標預設使用delete釋放它所關聯的物件。
shared_ptr<string> clone(int p)
{
//必須顯示地呼叫int *建立shared_ptr<int>
return shared_ptr<int>(new int(p));
}
不要混合使用普通指標和智慧指標
void process(shared_ptr<int> ptr)
{
//使用ptr
}//ptr離開作用域,被銷燬
process採用傳值方式傳遞形參,因此實參會被拷貝給一個臨時變數ptr,拷貝實參會遞增引用計數。
shared_ptr<int> p(new int(42));//引用計數為1;
process(p); //引用計數為2,執行完process後引用計數變為1
int i = *p;//p的引用計數為1;
智慧指標刪除器
struct destination;
struct connection;
connection connect(destination *d);
void disconnection(connection);
void f(destination *dd)
{
connection conn = connect(dd);
//使用完conn後並未及時關閉,需要單獨呼叫disconnection
}
以上程式碼中若connection存在解構函式,還可以在解構函式中呼叫disconnect。但是不存在解構函式,就可以使用shared_ptr,與採用shared_ptr自動會呼叫delete避免記憶體洩漏的原理是一樣的。
修改如下:
void end_connection(destionation *d){ disconnect(p); };
void f(destination *dd)
{
connection conn = connect(dd);
shared_ptr<connection> p(&conn, end_connection);
}
unique_ptr
某一時刻只能有一個unique_ptr指向一個給定物件,unique_ptr與物件是一一對應的關係。
unique_ptr<string> p1(new string("Stegosaurus"));
unique_ptr<string> p2(p1); //錯誤:unique_ptr不支援拷貝,unique_ptr沒有對應的拷貝建構函式
unique_ptr<string> p3;
p3 = p2; //錯誤:unique_ptr不支援拷貝,unique_ptr沒有對應的拷貝建構函式
unique_ptr操作
- unique_ptr〈T〉 u1:空unique_ptr,可以指向型別為T的物件;u1會使用delete來釋放它的指標。
- unique_ptr〈T, D〉 u2:u2會使用一個型別為D的可呼叫物件來釋放它的指標。
- unique_ptr〈T, D〉 u(d)
- u = nullptr
- u.release() :u放棄對指標的控制權,返回指標,並將u置為空
- u.reset():釋放u指向的物件
- u.reset(q):如果提供了內建q,令u指向這個物件;否則將u置位空。
指向release之後,unique_ptr會切斷與之前指向物件的聯絡,並返回當初指向的物件,這時就需要使用返回的物件初始化另一個智慧指標。
p2.release();//錯誤:p2不會釋放記憶體,而且我們丟失了指標
auto p = p2.release(); //正確,用完後必須delete(p)
weak_ptr操作
weak_ptr是一種不控制所指向物件生命週期的智慧指標,它指向一個由shared_ptr管理的物件,將一個weak_ptr繫結到shared_ptr上不會改變shared_ptr的引用計數。
- weak_ptr〈T〉w:指向型別為T的空weak_ptr
- weak_ptr〈T〉w(sp):與shared_ptr sp指向相同物件的weak_ptr,但是T必須能轉換為sp可以指向的型別
- w.reset()
- w.use_count();
- w.expired();
- w = p
相關文章
- C++基礎回顧4——動態陣列C++陣列
- 智慧指標之手撕共享指標shared_ptr指標
- C++智慧指標之shared_ptr與右值引用(詳細)C++指標
- C++ 智慧指標詳解: std::unique_ptr 和 std::shared_ptrC++指標
- 【指標】-簡單回顧指標
- C++智慧指標C++指標
- C++基於模板實現智慧指標C++指標
- 智慧指標思想實踐(std::unique_ptr, std::shared_ptr)指標
- 回顧JavaScript基礎——函式JavaScript函式
- C++進階(智慧指標)C++指標
- C#基礎委託回顧C#
- day001|python基礎回顧Python
- Java基礎知識回顧 -SQLJavaSQL
- UE4 智慧指標指標
- C指標原理(14)-C指標基礎指標
- C指標原理(15)-C指標基礎指標
- C++基礎回顧5——類的拷貝、複製和銷燬C++
- c++ 智慧指標用法詳解C++指標
- C++筆記(11) 智慧指標C++筆記指標
- 函式指標基礎函式指標
- C++ 用智慧指標這樣包裝 this 指標是否可行C++指標
- C++學習筆記基礎篇15——地址和指標C++筆記指標
- C++標準庫有四種智慧指標C++指標
- 傳統C++回顧C++
- 指標和標籤的基礎理解指標
- C++定義函式指標,回撥C#C++函式指標C#
- C語言基礎-指標C語言指標
- Android知識點回顧之Activity基礎Android
- Azure Data Factory(九)基礎知識回顧
- Android知識點回顧之Service基礎Android
- 【C++】智慧指標的正確使用方式C++指標
- C++ this 指標C++指標
- C++ 指標C++指標
- Java基礎知識回顧之六 —– IO流Java
- Java基礎知識回顧之六 ----- IO流Java
- 閱讀原始碼,通過LinkedList回顧基礎原始碼
- C語言基礎-1、指標C語言指標
- 【C++】 61_智慧指標類别範本C++指標