日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

this指针_c++11新特性之智能指针

發布時間:2025/3/21 c/c++ 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 this指针_c++11新特性之智能指针 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

很多人談到c++,說它特別難,可能有一部分就是因為c++的內存管理吧,不像java那樣有虛擬機動態的管理內存,在程序運行過程中可能就會出現內存泄漏,然而這種問題其實都可以通過c++11引入的智能指針來解決,相反我還認為這種內存管理還是c++語言的優勢,因為盡在掌握。

c++11引入了三種智能指針:

  • std::shared_ptr

  • std::weak_ptr

  • std::unique_ptr

shared_ptr

shared_ptr使用了引用計數,每一個shared_ptr的拷貝都指向相同的內存,每次拷貝都會觸發引用計數+1,每次生命周期結束析構的時候引用計數-1,在最后一個shared_ptr析構的時候,內存才會釋放。

使用方法如下:

struct ClassWrapper { ClassWrapper() {??????? cout?<"construct"?<endl; data = new int[10]; }????~ClassWrapper()?{ cout << "deconstruct" << endl; if (data != nullptr) { delete[] data; } } void Print() { cout?<"print"?<endl; } int* data;};void Func(std::shared_ptr ptr) {????ptr->Print();}int main() { auto smart_ptr = std::make_shared(); auto ptr2 = smart_ptr; // 引用計數+1 ptr2->Print(); Func(smart_ptr); // 引用計數+1 smart_ptr->Print(); ClassWrapper *p = smart_ptr.get(); // 可以通過get獲取裸指針 p->Print(); return 0;}

智能指針還可以自定義刪除器,在引用計數為0的時候自動調用刪除器來釋放對象的內存,代碼如下:

std::shared_ptr<int> ptr(new int, [](int *p){ delete p; });

關于shared_ptr有幾點需要注意:

? 不要用一個裸指針初始化多個shared_ptr,會出現double_free導致程序崩潰

? 通過shared_from_this()返回this指針,不要把this指針作為shared_ptr返回出來,因為this指針本質就是裸指針,通過this返回可能 會導致重復析構,不能把this指針交給智能指針管理。

class A { shared_ptr GetSelf() { return shared_from_this(); // return shared_ptr(this); 錯誤,會導致double free } };
  • 盡量使用make_shared,少用new。

  • 不要delete get()返回來的裸指針。

  • 不是new出來的空間要自定義刪除器。

  • 要避免循環引用,循環引用導致內存永遠不會被釋放,造成內存泄漏。

using namespace std;struct A;struct B;struct A { std::shared_ptr bptr; ~A() { cout << "A delete" << endl; }};struct B { std::shared_ptr aptr; ~B() { cout << "B delete" << endl; }};int main() { auto aaptr = std::make_shared(); auto bbptr = std::make_shared(); aaptr->bptr = bbptr; bbptr->aptr = aaptr; return 0;}

上面代碼,產生了循環引用,導致aptr和bptr的引用計數為2,離開作用域后aptr和bptr的引用計數-1,但是永遠不會為0,導致指針永遠不會析構,產生了內存泄漏,如何解決這種問題呢,答案是使用weak_ptr。

weak_ptr

weak_ptr是用來監視shared_ptr的生命周期,它不管理shared_ptr內部的指針,它的拷貝的析構都不會影響引用計數,純粹是作為一個旁觀者監視shared_ptr中管理的資源是否存在,可以用來返回this指針和解決循環引用問題。

  • 作用1:返回this指針,上面介紹的shared_from_this()其實就是通過weak_ptr返回的this指針,這里參考我之前寫的源碼分析shared_ptr實現的文章,最后附上鏈接。

  • 作用2:解決循環引用問題。

struct A;struct B;struct A { std::shared_ptr bptr; ~A() { cout << "A delete" << endl; } void Print() { cout << "A" << endl; }};struct B { std::weak_ptr aptr; // 這里改成weak_ptr ~B() { cout << "B delete" << endl; } void PrintA() { if (!aptr.expired()) { // 監視shared_ptr的生命周期 auto ptr = aptr.lock(); ptr->Print(); } }};int main() { auto aaptr = std::make_shared(); auto bbptr = std::make_shared(); aaptr->bptr = bbptr; bbptr->aptr = aaptr; bbptr->PrintA(); return 0;}輸出:AA deleteB delete

unique_ptr

std::unique_ptr是一個獨占型的智能指針,它不允許其它智能指針共享其內部指針,也不允許unique_ptr的拷貝和賦值。使用方法和shared_ptr類似,區別是不可以拷貝:

using namespace std;struct A { ~A() { cout << "A delete" << endl; } void Print() { cout << "A" << endl; }};int main() { auto ptr = std::unique_ptr(new A); auto tptr = std::make_unique(); // error, c++11還不行,需要c++14 std::unique_ptr tem = ptr; // error, unique_ptr不允許移動 ptr->Print(); return 0;}

unique_ptr也可以像shared_ptr一樣自定義刪除器,使用方法和shared_ptr相同。

關于c++11的智能指針的使用就介紹到這里,大家有問題可以點此留言 ,我會盡快回復~

參考資料

https://www.jianshu.com/p/b6ac02d406a0https://juejin.im/post/5dcaa857e51d457f7675360b#heading-16《深入應用c++11:代碼優化與工程級應用》

源碼分析shared_ptr實現之修訂版

一文讓你搞懂設計模式

RAII妙用之ScopeExit

深入淺出虛擬內存

深入淺出虛擬內存(二)繪制虛擬內存排布圖

深入淺出虛擬內存(三)堆內存分配及malloc實現原理

RAII妙用之計算函數耗時

一文吃透C++11中auto和decltype知識點

總結

以上是生活随笔為你收集整理的this指针_c++11新特性之智能指针的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。