C++特性——智能指針

為什么需要智能指針

對于定義的局部變量,當作用域結束之后,就會自動回收,這沒有什么問題。
當時用new delete的時候,就是動態分配對象的時候,如果new了一個變量,但卻沒有delete,這會造成內存泄露。
特別是當大型項目,會使用多個指針指向同一塊內存區域的時候,什么時候釋放這塊指針所指向的內存區域就成了一個問題。
智能指針就是解決這個問題的辦法,他的思想就是當你定義了一個智能指針,可以像普通指針一樣使用*??來獲取里面的內容,當用其他的智能指針再次指向這塊區域的時候,會有一個計數器。當所有的智能指針都被標記為不再使用的時候,這個計數器清零,這塊指針所指向的內存也就被釋放。

什么是動態分配的對象? 是指在程序運行時(而非編譯時)在堆(heap)內存中分配的對象。

注意

在使用智能指針的時候,一定要避免使用delete,可能會引發未定義的行為,就讓系統自己處理。
unique_ptr性能很好,不支持復制,唯一控制權;shared_ptr支持多個指針指向同一塊內存并計數,資源消耗大。
任何時候都推薦使用unique_ptr,而shared_ptr當多個函數

shared_ptr

引入#include <memory>
用法:shared _ptr<T> p = make_shared<T>()或者大括號的初始方法shared_ptr<T> p {fp, close_file}
例如shared _ptr<int> p = make_shared<int>(100)的意思就是定義了一個指向存儲內容為100的動態內存的共享指針p。此時p.use_count() 引用計數為1。
當定義其他的共享指針p1=p時,表示p1也指向了int類型的100的這塊內存,同理如果是對象,不會再構造一次,因為指向的是同一塊東西。此時再使用p.use_count()或者p1.use_count()得到的計數結果都是2。
p.reset()就表示重置p指向的內容,此時引用計數會減1,當p1.reset()p1也重置之后,引用計數為0,這塊內存被釋放。

額外補充

  1. p.reset()這個用法還可以在括號里p.reset(new int)代表指向一個新的int內存,舊的int內存減1
  2. 在新定義一個共享指針的時候,是可以對它的釋放功能自定義的,可以自定義為其他的功能,例如下圖將釋放功能自定義為文件關閉函數。當引用計數為0的時候,就可以自動關閉文件。
    在這里插入圖片描述
  3. 別名 shared_ptr<example_class> p1 {p, &(p->bar)} p1是p的別名

unique_ptr

引入#include <memory>
用法:unique_ptr<int> p = make_unique<int>(100)
unique_ptr就不存在復制這樣的功能,p獨享這一塊資源,不能和別的指針共享。
當作用域結束之后,unique_ptr指向的資源就會釋放,即使它是用的new delete來創建的。
可以使用p.get()獲取裸指針。
同樣的,可以使用p.reset()來重置unique_ptr使其指向nullptr。也可以p.reset(new class)來讓這個unique_ptr指向一個新的類。
可以使用p.release()來釋放p對這塊資源的控制權,會返回一個裸指針。unique_ptr中是沒有復制這么一說的,也就不存“=”的賦值。但是可以傳遞:通過unique<exapmle_class> p1 (p.release())或者是利用move,即unique_ptr<example_class> p1(p.move())
unnique_ptr可以自定義分配函數和自定義釋放函數,eg:
在這里插入圖片描述

unique_ptr的函數綁定是在編譯時就綁定了,這個函數成為了unique_ptr實例的一部分,而shared_ptr則是運行時綁定。

在函數之間的unique_ptr傳遞

指針在函數之間的傳遞難免不會發生復制,例如實參作為輸入進入函數之后,函數可能會復制一份進入函數體。
解決辦法:

  1. 函數的形參是一個unique_ptr的引用
  2. 只傳遞所指向的資源例如傳入*p,接收也是一個int& p。
  3. 利用p.get()或者是move(),這樣會傳遞一個裸指針到函數里去。

weak_ptr

weak_ptr是與shared_ptr成雙成對的,它只能作為一個觀察者
對資源的引用是非擁有式的,因此不能控制資源的釋放。當想使用weak_ptr來煩我跟對象,需要使用shared_ptr<int> spt = wp.lock()是會返回一個shared_ptr,然后就可以正常的使用*來訪問了

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/73693.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/73693.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/73693.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C語言之 循環語句:程序運行的核心動力(上)

個人主頁&#xff1a;strive-debug 在 C 語言中&#xff0c;分支結構可以通過 if、switch 語句來實現&#xff0c;循環結構則可以通過 for、while、do while 語句來實現。 if 語句 if 語句的語法形式如下&#xff1a; if (表達式)語句; 如果表達式成立&#xff08;為真&am…

FreeRTOSBug解析:一個任務printf打印一半突然跳轉另一個任務,導致另一個任務無法打印

bug現象&#xff1a; key任務&#xff1a; 默認任務&#xff1a; 此時兩個任務的優先級相同&#xff0c;搶占式調度&#xff0c;時間片輪轉&#xff0c;空閑任務讓步。 但是會出現一個問題&#xff0c;key任務在發送完隊列之后不會立即跳轉到默認任務的隊列接收函數后的print…

操作系統八股文整理(一)

操作系統八股文整理 一、進程和線程的區別二、進程與線程的切換過程一、進程切換進程切換的步驟&#xff1a; 二、線程切換線程切換的步驟&#xff1a; 三、進程切換與線程切換的對比四、上下文切換的優化 三、系統調用一、系統調用的觸發二、從用戶空間切換到內核空間三、執行…

卷積神經網絡(CNN)之 EfficientNet

在深度學習領域&#xff0c;模型的計算效率與性能之間的平衡一直是一個核心挑戰。隨著卷積神經網絡&#xff08;CNN&#xff09;在圖像分類、目標檢測等任務中取得顯著成果&#xff0c;模型的復雜度和計算需求也急劇增加。2019年&#xff0c;Google Research 提出的 EfficientN…

學生選課管理系統數據庫設計報告

學生選課管理系統數據庫設計報告 一、需求分析 &#xff08;一&#xff09;項目背景 學生選課管理系統是高校教學管理的重要組成部分&#xff0c;旨在實現學生選課、課程管理、成績錄入與查詢等功能的自動化和信息化。通過該系統&#xff0c;學生可以方便地選擇課程&#xf…

工具介紹《Awsome-Redis-Rogue-Server 與 redis-rogue-server》

1. 核心功能與攻擊場景 redis-rogue-server 基于Redis主從復制漏洞&#xff08;CVE未公開&#xff09;&#xff0c;針對Redis 4.x~5.0.5版本設計&#xff0c;通過偽造惡意主節點強制同步惡意模塊&#xff08;.so文件&#xff09;實現遠程代碼執行&#xff08;RCE&#xff09;。…

Razor C# 變量

Razor C# 變量 引言 在ASP.NET MVC和Razor視圖引擎中,變量是構建動態網頁的基礎。理解Razor C#變量的使用對于開發者來說至關重要。本文將詳細介紹Razor C#變量的概念、類型、作用域以及如何在實際項目中有效使用它們。 一、Razor C# 變量的概念 Razor C# 變量是存儲在Raz…

【QA】模板方法模式在Qt中有哪些應用?

在 Qt 框架中&#xff0c;模板方法模式&#xff08;Template Method Pattern&#xff09;被廣泛應用于框架的設計中&#xff0c;通過定義算法骨架并允許子類在不改變結構的情況下重寫部分步驟。以下是 Qt 中典型的應用場景及示例&#xff1a; 1. 事件處理&#xff08;Event Ha…

有趣的算法實踐:整數反轉與回文檢測(Java實現)

題目描述&#xff1a;整數反轉與回文檢測 要求實現兩個功能&#xff1a; 將輸入的整數反轉&#xff08;保留符號&#xff0c;如輸入-123返回-321&#xff09;判斷反轉后的數是否為回文數&#xff08;正反讀相同&#xff09; 示例&#xff1a; 輸入&#xff1a;123 → 反轉結…

【協作開發】低成本一鍵復刻github的gitea

在閱讀 next-public 時&#xff0c;反思原本的需求&#xff0c;是否本未倒置&#xff0c;故而重新調研當下開源現狀。發現 gitea 完全滿足商業軟件的開發要求&#xff0c;并且價格足夠低&#xff0c;使用足夠方便&#xff0c;其他同類軟件完全不用看了&#xff0c;真是世界級的…

基于“動手學強化學習”的知識點(二):第 15 章 模仿學習(gym版本 >= 0.26)

第 15 章 模仿學習&#xff08;gym版本 &#xff1e; 0.26&#xff09; 摘要 摘要 本系列知識點講解基于動手學強化學習中的內容進行詳細的疑難點分析&#xff01;具體內容請閱讀動手學強化學習&#xff01; 對應動手學強化學習——模仿學習 # -*- coding: utf-8 -*-import gy…

JAVA面試_進階部分_Java JVM:垃圾回收(GC 在什么時候,對什么東西,做了什么事情)

在什么時候&#xff1a; 首先需要知道&#xff0c;GC又分為minor GC 和 Full GC&#xff08;major GC&#xff09;。Java堆內存分為新生代和老年代&#xff0c;新生代 中又分為1個eden區和兩個Survior區域。 一般情況下&#xff0c;新創建的對象都會被分配到eden區&#xff…

2024年消費者權益數據分析

&#x1f4c5; 2024年315消費者權益數據分析 數據見&#xff1a;https://mp.weixin.qq.com/s/eV5GoionxhGpw7PunhOVnQ 一、引言 在數字化時代&#xff0c;消費者維權數據對于市場監管、商家誠信和行業發展具有重要價值。本文基于 2024年315平臺線上投訴數據&#xff0c;采用數…

設計模式Python版 訪問者模式

文章目錄 前言一、訪問者模式二、訪問者模式示例 前言 GOF設計模式分三大類&#xff1a; 創建型模式&#xff1a;關注對象的創建過程&#xff0c;包括單例模式、簡單工廠模式、工廠方法模式、抽象工廠模式、原型模式和建造者模式。結構型模式&#xff1a;關注類和對象之間的組…

安全無事故連續天數計算,python 時間工具的高效利用

安全天數計算&#xff0c;數據系統時間直取&#xff0c;安全標準高效便捷好用。 筆記模板由python腳本于2025-03-17 23:50:52創建&#xff0c;本篇筆記適合對python時間工具有研究欲的coder翻閱。 【學習的細節是歡悅的歷程】 博客的核心價值&#xff1a;在于輸出思考與經驗&am…

大型語言模型(LLM)部署中的內存消耗計算

在部署大型語言模型&#xff08;LLM&#xff09;時&#xff0c;顯存&#xff08;VRAM&#xff09;的合理規劃是決定模型能否高效運行的核心問題。本文將通過詳細的公式推導和示例計算&#xff0c;系統解析模型權重、鍵值緩存&#xff08;KV Cache&#xff09;、激活內存及額外開…

Mysql表的查詢

一&#xff1a;創建一個新的數據庫&#xff08;companydb),并查看數據庫。 二&#xff1a;使用該數據庫&#xff0c;并創建表worker。 mysql> use companydb;mysql> CREATE TABLE worker(-> 部門號 INT(11) NOT NULL,-> 職工號 INT(11) NOT NULL,-> 工作時間 D…

ASP.NET Webform和ASP.NET MVC 后臺開發 大概80%常用技術

本文涉及ASP.NET Webform和ASP.NET MVC 后臺開發大概80%技術 2019年以前對標 深圳22K左右 廣州18K左右 武漢16K左右 那么有人問了2019年以后的呢&#xff1f; 答&#xff1a;吉祥三寶。。。 So 想繼續看下文的 得有自己的獨立判斷能力。 C#.NET高級筆試題 架構 優化 性能提…

首頁性能優化

首頁性能提升是前端優化中的核心任務之一&#xff0c;因為首頁是用戶訪問的第一入口&#xff0c;其加載速度和交互體驗直接影響用戶的留存率和轉化率。 1. 性能瓶頸分析 在優化之前&#xff0c;首先需要通過工具分析首頁的性能瓶頸。常用的工具包括&#xff1a; Chrome DevTo…

一周學會Flask3 Python Web開發-SQLAlchemy刪除數據操作-班級模塊

鋒哥原創的Flask3 Python Web開發 Flask3視頻教程&#xff1a; 2025版 Flask3 Python web開發 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili 首頁list.html里加上刪除鏈接&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta c…