make_shared的使用

目錄

1.?make_shared 的基本概念

基本用法

2. 引入 make_shared 的主要原因

2.1 解決傳統構造方式的問題

2.2 標準委員會的動機

3. make_shared 的核心優勢

3.1 性能優勢(最重要優點)

內存分配優化:

性能提升表現:

3.2 異常安全(關鍵優勢)

3.3 代碼簡潔性(顯著優勢)

配合 auto 使用更清晰:

4. make_shared 的實現原理

4.1 典型實現偽代碼


1.?make_shared 的基本概念

make_shared?是 C++11 引入的模板函數,用于創建并返回一個指向動態分配對象的?shared_ptr。它是創建共享所有權對象的標準推薦方式。

基本用法
auto ptr = std::make_shared<MyClass>(arg1, arg2...);

2. 引入 make_shared 的主要原因

2.1 解決傳統構造方式的問題

傳統?shared_ptr?構造方式:

std::shared_ptr<MyClass> ptr(new MyClass(arg1, arg2...));

這種方式存在三個潛在問題:

  • 內存分配分離:需要兩次內存分配(對象+控制塊)
  • 異常不安全:可能在構造過程中發生內存泄漏
  • 代碼冗余:需要重復類型名稱

異常導致泄漏的場景

當執行?std::shared_ptr<MyClass> ptr(new MyClass(arg1, arg2...))?時,實際分為兩個關鍵內存操作:

  • 執行?new MyClass(arg1, arg2...)分配 “對象本身” 的內存,并調用構造函數初始化?MyClass?對象。
  • 構造?shared_ptr分配 “控制塊” 的內存(控制塊用于記錄引用計數、弱引用計數等元信息),然后讓?shared_ptr?接管第一步創建的對象。

如果在 ** 步驟 2(分配控制塊)** 時發生異常(比如內存不足,拋出?std::bad_alloc),問題就會出現:

  • 步驟 1 已經成功創建了?MyClass?對象(內存已分配,構造函數已執行)。
  • 但步驟 2 失敗,shared_ptr?沒有被成功構造,也就沒有指針能管理第一步創建的對象
  • 最終,這個?new?出來的?MyClass?對象既沒有被智能指針接管,也沒有被手動?delete,導致內存泄漏(對象的內存永遠無法被釋放)。
2.2 標準委員會的動機

C++標準委員會引入 make_shared 主要基于:

  • 性能優化:減少內存分配次數
  • 異常安全:保證原子性操作
  • 代碼簡潔:改善編碼體驗

3. make_shared 的核心優勢

3. make_shared 的核心優勢

3.1 性能優勢(最重要優點)
內存分配優化:

典型實現的內存布局

make_shared 分配的內存塊:
+-------------------+-------------------+
| 控制塊 (refcount) | 對象數據          |
+-------------------+-------------------+
性能提升表現:
  • 緩存友好:控制塊和對象在同一緩存行
  • 減少碎片:單次分配減少內存碎片
  • 分配更快:內存分配是昂貴操作

基準測試通常顯示?make_shared?比傳統方式快 10-30%

3.2 異常安全(關鍵優勢)

考慮以下可能拋出異常的代碼:

void process(std::shared_ptr<X> x, std::shared_ptr<Y> y);process(std::shared_ptr<X>(new X), std::shared_ptr<Y>(new Y));

問題在于:

  • new X?成功
  • new Y?拋出異常
  • 已分配的 X 內存泄漏

解釋

  • 先執行?new X,成功分配了?X?類型的內存,并得到裸指針?X*
  • 接著執行?new Y,但此時內存不足(或其他原因),new Y?拋出異常(比如?std::bad_alloc)。

異常導致 “裸指針未被智能指針接管”

當?new Y?拋出異常時,整個?process?函數的調用會被中斷。此時:

  • 第一個參數?std::shared_ptr<X>(new X)?還沒完成 “shared_ptr?封裝裸指針” 的過程(因為參數計算被異常打斷了);
  • 也就是說,new X?分配的內存,只有裸指針,沒有被?shared_ptr?接管(智能指針的 “自動釋放” 能力沒生效)。

使用?make_shared?的解決方案:

process(std::make_shared<X>(), std::make_shared<Y>());

這樣要么全部成功,要么全部回滾,不會泄漏資源。

3.3 代碼簡潔性(顯著優勢)
// 傳統方式(重復類型名)
std::shared_ptr<VeryLongTypeName> p(new VeryLongTypeName(args...));// make_shared 方式(簡潔)
auto p = std::make_shared<VeryLongTypeName>(args...);
配合 auto 使用更清晰:
auto widget = std::make_shared<Widget>(color, size);

4. make_shared 的實現原理

4.1 典型實現偽代碼
//make_shared的實現
//偽代碼
template<typename T, typename... Args>
shared_ptr<T> my_make_shared(Args&& ...args)
{//先開辟控制塊和對象大小的空間void* p = ::operator new(sizeof(ContorlBlock) + sizeof(T));//構造控制塊ContorlBlock* cb = new(p) ControlBlock();//獲取到對象的地址T* obj = reinterpret_cast<T*>(static_cast<char*>(p) + sizeof(ContorlBlock));//給對象進行構造 使用定位new,使用完美轉發保持右值屬性new(obj) T(std::forward(Args)(args)...);return shared_ptr<T>(cb, obj);
}	

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

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

相關文章

基于 Gemini 的 CI/CD 自動化測評 API 集成實戰教程

在現代軟件開發中&#xff0c;CI/CD 集成 已經成為必不可少的流程。它不僅能幫助團隊快速迭代&#xff0c;還能通過自動化手段提升代碼質量。而在編程培訓和團隊內部學習中&#xff0c;如何引入 自動化測評 API&#xff0c;實現提交即測評、即時反饋呢&#xff1f;本文將以 Gem…

SOME/IP-SD(Service Discovery)協議的核心協議

<摘要> 本解析以AutoSAR AP R22-11版本為基準&#xff0c;全面系統地闡述了SOME/IP-SD&#xff08;Service Discovery&#xff09;協議的核心內容。從車載網絡演進背景切入&#xff0c;詳細剖析了面向服務架構&#xff08;SOA&#xff09;下服務發現的必要性&#xff0c;…

視頻串行解串器(SerDes)介紹

視頻串行解串器&#xff08;SerDes&#xff09;是高速數據通信中的核心接口技術&#xff0c;通過串行化與解串行化實現視頻信號的高效傳輸&#xff0c;廣泛應用于汽車電子、數據中心、高清視頻傳輸等領域。 一、技術原理串行化&#xff08;Serializer&#xff09; 功能&#xf…

哈士奇vs網易高級數倉:數據倉庫的靈魂是模型、數據質量還是計算速度?| 易錯題

面試場景 面試官: (微笑,營造輕松但專業的氛圍)嗨,哈士奇,歡迎來參加網易的二面。我看你簡歷上數據倉庫的項目經驗很豐富,我們今天就深入聊聊。我這里有一個經典的問題想聽聽你的看法:在你看來,數據倉庫的靈魂是模型、數據質量還是計算速度? 哈士奇: (不假思索,…

貪心算法應用:3D打印支撐結構問題詳解

Java中的貪心算法應用&#xff1a;3D打印支撐結構問題詳解 1. 問題背景與概述 1.1 3D打印中的支撐結構問題 在3D打印過程中&#xff0c;當模型存在懸空部分&#xff08;overhang&#xff09;時&#xff0c;通常需要添加支撐結構&#xff08;support structure&#xff09;來防止…

Python爬蟲實戰:研究3D plotting模塊,構建房地產二手房數據采集和分析系統

1. 引言 1.1 研究背景 在大數據與人工智能技術快速發展的背景下,數據已成為驅動決策的核心要素。互聯網作為全球最大的信息載體,蘊含海量結構化與非結構化數據,如何高效提取并分析這些數據成為學術界與產業界的研究熱點。 網絡爬蟲技術通過自動化請求與解析網頁,實現數據…

Gradio全解10——Streaming:流式傳輸的音頻應用(7)——ElevenLabs:高級智能語音技術

Gradio全解10——Streaming&#xff1a;流式傳輸的音頻應用&#xff08;7&#xff09;——ElevenLabs&#xff1a;高級智能語音技術10.7 ElevenLabs&#xff1a;高級智能語音技術10.7.1 核心功能與可用模型1. 核心功能與產品2. 三類語音模型10.7.2 文本轉語音API1. 完整操作步驟…

【桃子同學筆記4】PCIE訓練狀態機(LTSSM)基礎

首先&#xff0c;所謂LTSSM&#xff0c;即&#xff1a;Link Training and Status State Machine&#xff08;鏈路訓練及狀態機&#xff09; 下圖為 LTSSM 的狀態機及訓練過程&#xff1a; LTSSM 包含 11 個頂層狀態&#xff1a;Detect、Polling、Configuration、Recovery、L0、…

STM32傳感器模塊編程實踐(十五)DIY語音對話控制+滿溢檢測智能垃圾桶模型

文章目錄 一.概要二.實驗模型原理1.硬件連接原理框圖2.控制原理 三.實驗模型控制流程四.語音控制垃圾桶模型程序五.實驗效果視頻六.小結 一.概要 以前介紹的智能垃圾桶模型都是通過超聲波模塊感知控制&#xff0c;這次介紹一款新的智能垃圾桶&#xff0c;直接使用語音交互模塊…

[bat-cli] docs | 控制器

鏈接&#xff1a;https://github.com/sharkdp/bat 前文傳送&#xff1a; 【探索Linux命令行】從基礎指令到高級管道操作的介紹與實踐【Linux命令行】從時間管理-&#xff1e;文件查找壓縮的指令詳解【Linux】1w詳解如何實現一個簡單的shell docs&#xff1a;bat bat 是一個*…

無線自動信道調整

通過信道調整功能&#xff0c;可以保證每個AP 能夠分配到最優的信道&#xff0c;盡可能地 減少和避免相鄰信道干擾&#xff0c;而且通過實時信道檢測&#xff0c;使AP 實時避開雷達&#xff0c;微波爐等干擾源。 動態信道調整能夠實現通信的持續進行&#xff0c;為網絡的可靠傳…

ios面試八股文

??Swift 語言特性??&#xff1a;請解釋一下 struct和 class的主要區別。特性????struct (值類型)????class (引用類型)????類型本質??值類型 (復制時創建獨立副本)引用類型 (復制時共享同一實例)??內存分配??通常在棧上 (更快速)在堆上 (需要ARC管理)??…

IntelliJ IDEA 2023更新git憑據

背景&#xff1a;已知原來從遠程倉庫獲取的項目&#xff0c;需要更新git用戶和密碼&#xff0c;但是又不想刪除本地項目環境&#xff08;不想重新獲取新建項目&#xff09;。報錯&#xff1a;remote: HTTP Basic: Access denied. The provided password or token is incorrect …

Docker 容器 OOM:從資源監控到JVM調優的實戰記錄

人們眼中的天才之所以卓越非凡&#xff0c;并非天資超人一等而是付出了持續不斷的努力。1萬小時的錘煉是任何人從平凡變成超凡的必要條件。———— 馬爾科姆格拉德威爾 &#x1f31f; Hello&#xff0c;我是Xxtaoaooo&#xff01; &#x1f308; “代碼是邏輯的詩篇&#xff…

【開題答辯全過程】以 基于微信小程序的寵物領養系統為例,包含答辯的問題和答案

個人簡介一名14年經驗的資深畢設內行人&#xff0c;語言擅長Java、php、微信小程序、Python、Golang、安卓Android等開發項目包括大數據、深度學習、網站、小程序、安卓、算法。平常會做一些項目定制化開發、代碼講解、答辯教學、文檔編寫、也懂一些降重方面的技巧。感謝大家的…

【可信數據空間-連接器狀態監控-Java代碼集成】

可信數據空間-連接器狀態監控-Java代碼集成一、 核心概念1. Micrometer2. Micrometer Registry Prometheus3.Prometheus二、 依賴配置 (Maven)三、 集成步驟與代碼示例場景一&#xff1a;在 Spring Boot 應用中集成&#xff08;最簡單&#xff09;1. 添加依賴&#xff08;如上所…

反編譯分析C#閉包

一、問題描述&#xff1a;比如有這樣的代碼&#xff1a;它的輸出結果是 3&#xff0c;3&#xff0c;3。通過搜索得知這一現象是因為C#閉包導致的.我們借助ILSpy看下IL中間代碼&#xff0c;首先它生成了一個名叫DisplayClass的類&#xff0c;類中定義了i的字段主代碼&#xff1a…

卷積神經網絡(CNN):從圖像識別原理到實戰應用的深度解析

目錄一.CNN的技術必要性&#xff1a;破解傳統圖像處理的兩大核心痛點痛點1&#xff1a;特征依賴人工設計&#xff0c;通用性差痛點2&#xff1a;全連接網絡參數爆炸&#xff0c;訓練難收斂二.CNN的核心原理&#xff1a;兩大機制與分層感知邏輯1.核心機制1&#xff1a;局部連接&…

用 SPL 編寫阿里云 FC2.0 函數

前言 在數字化轉型持續加速的背景下&#xff0c;企業越來越多地將業務邏輯以服務化方式部署至云端。阿里云函數計算&#xff08;Function Compute&#xff0c;簡稱FC&#xff09;作為一種無服務器計算平臺&#xff0c;屏蔽了底層資源運維的復雜性&#xff0c;使開發者能夠專注…

AR 巡檢與普通巡檢有哪些區別,有哪些優勢|阿法龍XR云平臺

AR 巡檢&#xff08;增強現實巡檢&#xff09;與普通巡檢&#xff08;傳統人工巡檢&#xff09;在技術應用、效率、準確性等多個維度存在顯著差異&#xff0c;具體區別如下&#xff1a; 1. 巡檢方式更智能 普通巡檢&#xff1a;依賴人工現場觀察&#xff0c;主要通過眼看、手…