C++11 智能指針

来源:https://www.cnblogs.com/biu-we/archive/2020/07/23/13367198.html
-Advertisement-
Play Games

智能指針可以對動態資源進行管理,保證任何情況下,已經構造的對象能夠安全的自動銷毀。 ...


前言

  • 智能指針可以對動態資源進行管理,保證任何情況下,已經構造的對象能夠安全的自動銷毀。說人話就是防止記憶體泄漏。
  • C++裡面共有四個智能指針:auto_ptr、unique_ptr、shared_ptr、weak_ptr,第一個已經C++11拋棄,後三個是c++11所支持。

auto_prt 所有權模式

auto_ptr<string> ap1 (new string ("hello,world")); 
auto_ptr<string> ap2;
ap2=ap1
//這裡不會報錯,ap2剝奪ap1的許可權,但程式訪問ap1會報錯,ap1被廢棄。auto_ptr缺點是:存在潛在的程式崩潰問題。

unique_ptr 獨占指針

  • 獨占指針所指向的記憶體為自己獨有,同一時刻只能有一個unique_ptr。指向給定的對象unique_ptr 對象不支持同類賦值和拷貝。

unique_ptr<int> up1(new int(2333));
unique_ptr<int> up2 = up1;//這裡會報錯,嘗試引用已刪除的函數。

//將原來up1指向記憶體交由up3指向
unique_ptr<int> up3 = std::move(up1);
cout << *up3 << endl;
cout << *up1 << endl;//內部已經將原來的指向設置為了nullptr但是並沒有刪除

//如果是reset帶參調用
unique_ptr<int> up4(new int(2333));
up4.reset(new int(9999));//將原來指向的2333刪除掉重新指向9999
cout << *up4 << endl;

up4 = nullptr;//相當於up4.reset(nullptr);
//cout << *up4 << endl;

unique_ptr<int> up5(new int(777));
int* p5 = up5.release();//將記憶體的控制權交給接受的指針,自己賦值為nullptr,但是沒有刪除
//cout << *up5 << endl;//已經失去了對之前記憶體的控制
cout << *p5 << endl;
delete p5;//需要手動釋放

shared_ptr 共用指針

  • 允許多個該智能指針共用一個堆記憶體。通過引用計數來實現共同管理和安全釋放,只有引用計數為0的時候才會刪除該對象的記憶體,支持賦值和拷貝的
shared_ptr<int> sp1(new int(123));
cout << sp1.use_count() << endl;
shared_ptr<int> sp2 = sp1;//增加了引用計數
cout << sp2.use_count() << endl;
cout << *sp1 << " " << *sp2 << endl;

sp1.reset();//對計數進行了減1,並且sp1退出了對共用的記憶體的管理
cout << sp2.use_count() << endl;//1
cout << sp1.use_count() << endl;//0
cout << sp2.unique() << endl;//判斷當前是否為獨占(是否只有一個引用對象)

sp1 = sp2;
cout << sp2.use_count() << endl;//2
cout << sp1.use_count() << endl;//2
//共用指針之間可以交換
shared_ptr<int> sp3(new int(456));
sp2.swap(sp3);//將sp2指向和sp3指向進行了交換,對應的引用計數的變化要清楚
cout << sp1.use_count() << endl;//2
cout << sp2.use_count() << endl;//1
cout << sp3.use_count() << endl;//2
shared_ptr<int> sp4 = sp2;
//獲取共用指針的原始指針
int* p = sp2.get();
cout << p[0] << endl;
p[0] = 321;
cout << *sp4 << endl;

//安全的使用共用指針,推薦使用make_shared函數來進行共用指針對象的創建
shared_ptr<int> sp5 = make_shared<int>();
cout << *sp5 << endl;
shared_ptr<int> sp6 = make_shared<int>(9527);
cout << *sp6 << endl;
shared_ptr<string> sp7 = make_shared<string>(10, '9');
cout << *sp7 << endl;

weak_ptr 弱指針

  • 主要是為了配合shared_ptr而引入的一種智能指針,只要為瞭解決迴圈引用的問題。
  • 可以從一個shared_ptr或者另一個weak_ptr對象來構造,但是它的構造和析構不會對引用計數產生實質的影響。
  • 並且沒有重載*,->這樣的指針操作,也就是說weak_ptr對象是沒有辦法當做指針直接使用的。如果要使用,可以通過lock函數獲得一個shared_ptr對象來使用。
shared_ptr<A> aa = make_shared<A>();
shared_ptr<B> bb = make_shared<B>();
//執行結束以後記憶體沒有被釋放,迴圈引用導致的
aa->b = bb;//2
bb->a = aa;//2

//改用弱指針可以消除迴圈引用的弊端
aa->wb = bb;//1
bb->wa = aa;//1

總結

  • 智能指針雖然幫忙管理記憶體,但是帶來程式運行效率的下降。
  • 主要根據自己的需求來靈活使用。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 模板 模版是純文本文件,可以生成任何基於文本的文件格式,比如HTML,XML,CSV等。Django模版語言致力於在性能和簡單性上取得平衡。Django的模版系統並不是簡單的將Python嵌入到HTML中。 下麵是一個小模版,它展示了一些基本的元素。 {% extends "base_generic ...
  • 5G的到來證明瞭互聯網行業發展一如既往的快,作為一名開發人員(Java崗)夢想自然是互聯網行業的大廠,這次我的一個學員拿到了杭州的一個研究院offer,透露一下,年薪50多萬,保底16,在這裡分享一撥面試過程! 一面 自我介紹,主要講講做了什麼和擅長什麼 設計模式瞭解哪些? AtomicIntege ...
  • 先來看看本節知識的結構圖吧! 接下來我們就逐步來看一下所有的知識點: 結構的演化 C++中的類是從結構演變而來的, 所以我們可以稱C++為”帶類的C”. 結構發生質的演變 C++結構中可以定義函數, 稱之為成員函數 結構定義格式, 像這樣: struct 結構名 { 數據成員; 成員函數; }; / ...
  • 這幾年為什麼Python在中國就火起來了? Python這個東西國,大概是從2017年末開始,突然就火了起來的。此前,對於Python,乃至編程,絕大多數程度上都是專業人士的話題,在普通大眾層面上起不了波瀾。在中國,大概是從2017年末開始,突然就火了起來的。此前,對於Python,乃至編程,絕大多 ...
  • 1.首先手機安裝Xposed(app) 2.安裝Fdex2(app) 3.打開Fdex2 4.點擊要脫殼的app 5.adb pull (點擊脫殼app時候彈出的來的路徑) 保存本地路徑 6.完結-.- 後面湊字數........................................... ...
  • 例如導出指定文件夾中的所有mp4文件的文件名 1 @echo off 2 for /r C:\Users\Administrator\Desktop\video %%i in (*.mp4) do ( 3 echo %%i 4 echo %%i>>C:\Users\Administrator\Des ...
  • 看到一篇關於Java學習體系的總結,在這裡給大家分享一下: 一、Java SE部分 java基礎:基礎語法;面向對象(重點);集合框架(重點);常見類庫API;java界面編程:AWT;事件機制;Swing;java高級知識:Annotation;IO和NIO、AIO;多線程、線程池;阻塞、非阻塞、 ...
  • 介面概述: 1、介面是Java語言中的一種引用類型,是方法的"集合",所以介面的內部主要就是定義方法,包含常量,抽象方法(JDK 7及以前),額外增加預設方法和靜態方法(JDK 8),額外增加私有方法(jdk9)。 介面的定義,它與定義類方式相似,但是使用 interface 關鍵字。它也會被編譯成 ...
一周排行
    -Advertisement-
    Play Games
  • 1、預覽地址:http://139.155.137.144:9012 2、qq群:801913255 一、前言 隨著網路的發展,企業對於信息系統數據的保密工作愈發重視,不同身份、角色對於數據的訪問許可權都應該大相徑庭。 列如 1、不同登錄人員對一個數據列表的可見度是不一樣的,如數據列、數據行、數據按鈕 ...
  • 前言 上一篇文章寫瞭如何使用RabbitMQ做個簡單的發送郵件項目,然後評論也是比較多,也是準備去學習一下如何確保RabbitMQ的消息可靠性,但是由於時間原因,先來說說設計模式中的簡單工廠模式吧! 在瞭解簡單工廠模式之前,我們要知道C#是一款面向對象的高級程式語言。它有3大特性,封裝、繼承、多態。 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 介紹 Nodify是一個WPF基於節點的編輯器控制項,其中包含一系列節點、連接和連接器組件,旨在簡化構建基於節點的工具的過程 ...
  • 創建一個webapi項目做測試使用。 創建新控制器,搭建一個基礎框架,包括獲取當天日期、wiki的請求地址等 創建一個Http請求幫助類以及方法,用於獲取指定URL的信息 使用http請求訪問指定url,先運行一下,看看返回的內容。內容如圖右邊所示,實際上是一個Json數據。我們主要解析 大事記 部 ...
  • 最近在不少自媒體上看到有關.NET與C#的資訊與評價,感覺大家對.NET與C#還是不太瞭解,尤其是對2016年6月發佈的跨平臺.NET Core 1.0,更是知之甚少。在考慮一番之後,還是決定寫點東西總結一下,也回顧一下.NET的發展歷史。 首先,你沒看錯,.NET是跨平臺的,可以在Windows、 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 添加節點(nodes) 通過上一篇我們已經創建好了編輯器實例現在我們為編輯器添加一個節點 添加model和viewmode ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...
  • 類型檢查和轉換:當你需要檢查對象是否為特定類型,並且希望在同一時間內將其轉換為那個類型時,模式匹配提供了一種更簡潔的方式來完成這一任務,避免了使用傳統的as和is操作符後還需要進行額外的null檢查。 複雜條件邏輯:在處理複雜的條件邏輯時,特別是涉及到多個條件和類型的情況下,使用模式匹配可以使代碼更 ...
  • 在日常開發中,我們經常需要和文件打交道,特別是桌面開發,有時候就會需要載入大批量的文件,而且可能還會存在部分文件缺失的情況,那麼如何才能快速的判斷文件是否存在呢?如果處理不當的,且文件數量比較多的時候,可能會造成卡頓等情況,進而影響程式的使用體驗。今天就以一個簡單的小例子,簡述兩種不同的判斷文件是否... ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...