RAII簡介

📦 一、技術原理簡介:RAII是個“托管狂魔”

想象你有個健忘的朋友,每次借東西都會忘記歸還。RAII(Resource Acquisition Is Initialization,資源獲取即初始化)就是C++派來的“超級管家”:

“你負責借,我負責還!”

核心邏輯

  1. 出生即打工:對象在構造函數里獲取資源(內存、文件、鎖等)。
  2. 去世前還債:對象在析構函數里自動釋放資源。
  3. 死也要還:即使程序中途崩潰(如拋異常),對象死前也會調用析構函數清理資源!

👉 本質資源的命,就是對象的命! 對象活著,資源有效;對象去世,資源釋放。


🔍 二、核心功能解析:RAII的三大絕招

1?? 自動釋放:告別手動delete/close

傳統代碼像總忘記關冰箱門:

void riskyFile()
{FILE* file = fopen("data.txt", "r"); // 借冰箱readData(file); // 用冰箱// 如果這里拋異常?冰箱門永遠開著!fclose(file); // 可能忘關!
}

RAII版:冰箱門自動關!

class FileHandler {
public:FileHandler(const string& path) {fileHandle = fopen(path.c_str(), "r"); 	// 出生即開門}~FileHandler() { if (fileHandle) fclose(fileHandle); 	// 死前必關門}
private:FILE* fileHandle = nullptr;
};void safeFile() {FileHandler fridge("data.txt"); // 開門throw "Oops! 冰箱炸了!"; 
} // 即使爆炸,析構也會關門! [1,3](@ref)

2?? 異常安全:崩潰也不留爛攤子

C++規定:拋異常時,所有活著的對象必須“死前清理”(棧展開調用析構函數)。

void doJob() {std::lock_guard<std::mutex> lock(mutex); // 出生即鎖門throw "程序崩了!"; 
} // 即使崩了,lock析構時自動解鎖![7](@ref)

3?? 禁止拷貝,支持移動:資源只能有一個爹

RAII對象默認“獨占資源”(如文件句柄只能被一個對象管理)。想轉讓資源?用移動語義

class Socket {
public:Socket() { /* 搶資源 */ }~Socket() { /* 釋放資源 */ }// 禁用拷貝(防止多個對象搶同一資源)Socket(const Socket&) = delete;// 支持移動(資源過戶)Socket(Socket&& other) noexcept { resource = other.resource;other.resource = nullptr; // 原對象變窮光蛋}
};

🧪 三、基礎代碼示例:手搓一個RAII類

需求:管理一段臨時內存(比如緩存區)

class MemoryPool {
public:// 1. 構造即搶資源MemoryPool(size_t size) : buffer(new char[size]) {cout << "搶到" << size << "字節內存!" << endl;}// 2. 析構必釋放~MemoryPool() noexcept {delete[] buffer;cout << "釋放內存!絕不賴賬!" << endl;}// 3. 禁用拷貝(避免重復釋放)MemoryPool(const MemoryPool&) = delete;MemoryPool& operator=(const MemoryPool&) = delete;// 4. 支持移動(資源過戶)MemoryPool(MemoryPool&& other) noexcept : buffer(other.buffer) {other.buffer = nullptr; // 原對象變窮光蛋}char* get() const { return buffer; }private:char* buffer;
};// 使用示例
void processData() {MemoryPool pool(1024); // 申請1KB緩存loadData(pool.get()); 
} // 函數結束 → pool去世 → 自動釋放內存![5,7](@ref)

🚀 四、應用場景舉例:RAII在C++中的“全家桶”

資源類型RAII封裝工具功能
動態內存std::unique_ptr自動delete,防內存泄漏
文件句柄std::fstream自動打開關閉文件
互斥鎖std::lock_guard作用域結束自動解鎖,防死鎖
網絡連接自定義Socket異常時自動斷開連接
數據庫連接連接池 + shared_ptr引用計數為0時自動歸還連接

智能指針實戰

void safeMemory() {auto ptr = std::make_unique<int>(42); // 構造即搶內存throw "內存溢出?無所謂!"; 
} // ptr析構 → 自動delete!穩如老狗

鎖管理實戰

std::mutex mtx;
void safeWithdraw() {std::lock_guard<std::mutex> lock(mtx); // 加鎖withdrawMoney(); // 任意操作
} // 函數結束 → lock析構 → 自動解鎖!防死鎖

?? 五、優勢對比:RAII vs 手動管理

對比項RAII手動管理結果
資源釋放自動(析構函數調用)需手動delete/closeRAII防漏
異常安全性? 強保證(析構必執行)? 脆弱(異常路徑易漏釋放)RAII更可靠
代碼復雜度邏輯內聚,代碼簡潔釋放代碼分散,重復書寫RAII更易維護
多資源管理成員按聲明逆序析構,自動協調需手動控制釋放順序RAII更安全
程序員負擔只需記住:對象活著=資源有效時刻惦記“借了要還”RAII解放大腦!

經典翻車現場(手動管理)

void manualFile() {FILE* f = fopen("data.txt", "r");if (!check(f)) return; // 直接return?文件沒關!parse(f); fclose(f); // 可能永遠執行不到
}

💎 總結:為什么C++程序員愛死RAII?

  1. 懶人福音:資源獲取釋放全自動化,告別new/delete噩夢。
  2. 異常克星:程序崩了也不留資源爛攤子。
  3. 代碼美容師:業務邏輯和資源管理分離,代碼更清爽。

記住RAII三字訣:
??“出生搶,死前還,異常崩了也不欠!”??

下次寫C++時,請對你的RAII對象說:

“好好打工,死前記得還債!” 😉

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

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

相關文章

微信小程序入門實例_____打造你的專屬單詞速記小程序

上次通過天氣查詢小程序&#xff0c;我們初探了微信小程序開發的世界。這次&#xff0c;咱們再挑戰一個有趣又實用的項目 ——“單詞速記小程序”。無論是學生黨備考&#xff0c;還是上班族提升英語&#xff0c;都能用得上&#xff01;接下來就跟著我&#xff0c;一步一步把它做…

gateway白名單存儲nacos,改成存儲數據庫

前言 很久沒寫博客了&#xff0c;csdn都開始ai潤色了&#xff0c;之前都是看相應框架的源碼看了個遍&#xff0c;感覺底層原理都差不多&#xff0c;這陣子著手改造了下gateway中的白名單&#xff0c;之前白名單存儲到nacos&#xff0c;要改成存到數據庫。里面涉及到淺淺的源碼…

ubentu服務器版本安裝Dify

Docker 中安裝Dify 首先安裝Docker 1. 克隆Dify代碼倉庫 從github克隆 Dify 源代碼至要本地環境。 我的ubentu服務器版本&#xff0c;我把源代碼下載到 /var/下 在var文件夾下執行 git clone https://github.com/langgenius/dify.git執行成功后&#xff0c;進入Dify源代碼的…

Redis分布式鎖實戰:從入門到生產級方案

目錄 一、為什么需要分布式鎖&#xff1f; 二、Redis分布式鎖核心特性 三、實現方案與代碼詳解 方案1&#xff1a;基礎版 SETNX EXPIRE 原理 代碼示例 問題 方案2&#xff1a;Redisson框架&#xff08;生產推薦&#xff09; 核心特性 代碼示例 優勢 方案3&#xff…

【Redis】StringRedisTemplate 和 RedisTemplate 的區別

StringRedisTemplate 和 RedisTemplate 是 Spring Data Redis 提供的兩種用于操作 Redis 的模板類&#xff0c;它們的核心區別在于 序列化方式 和 操作的數據類型。以下是兩者的主要區別和使用建議&#xff1a; ? 1. 數據類型支持 類名支持的數據類型說明RedisTemplate支持所…

docker-compose快速搭建redis集群

目錄結構 redis-cluster/ ├── config/ │ ├── master.conf │ ├── slave1.conf │ └── slave2.conf └── docker-compose.yml配置文件內容 1. config/master.conf # Redis主節點配置 port 6379 bind 0.0.0.0 protected-mode no logfile "redis-mas…

SpringCloud系列(39)--SpringCloud Gateway常用的Route Predicate

前言&#xff1a;在上一節中我們實現了SpringCloud Gateway的動態路由 &#xff0c;而在本節中我們將著重介紹各種Route Predicate的作用。 1、可以到官方文檔里查看常用的Route Predicate的種類 https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.REL…

漸變色的進度條控件

近日&#xff0c;用VB.net2003重寫了一個漸變色的進度條控件。主要有以下功能&#xff1a; 支持自定義進度條分段數量&#xff0c;可拆分為多個步驟&#xff1b;每個步驟可獨立顯示完成百分比及漸變色效果。 每個步驟均可配置任務名稱和描述&#xff1b;運行時能實時顯示當前執…

【DICOM后處理】qt+vs 實現DICOM數據四視圖顯示

目錄 1、DICOM四視圖2、vtkImageViewer2 實現二維平面圖顯示3、vtkVolume實現三維體數據顯示4、實現界面圖 1、DICOM四視圖 DICOM四視圖通常指同時顯示醫學影像的四個不同平面或視角&#xff0c;用于全面分析三維數據&#xff08;如CT、MRI等&#xff09;。 標準四視圖布局&a…

Google Maps 安裝使用教程

一、Google Maps 簡介 Google Maps 是谷歌提供的地圖服務&#xff0c;通過其 JavaScript API&#xff0c;開發者可以在網頁中嵌入地圖&#xff0c;添加標記、路徑、地理編碼、路線導航等功能&#xff0c;適用于位置展示、物流追蹤、LBS 應用等場景。 二、獲取 Google Maps API…

Nginx+Keepalived實現前臺服務高可用

現階段項目開發往往采用前后臺分離&#xff0c;前臺常用的技術有vue、react等&#xff0c;前臺代碼部署在nginx中&#xff0c;代碼中配置了后臺服務的網關地址&#xff0c;由網關向后臺分發服務請求&#xff0c;架構示意圖如下&#xff1a; 在上述架構圖中&#xff0c;如果Ngin…

Gradio全解13——MCP協議詳解(5)——Python包命令:uv與uvx實戰

Gradio全解13——MCP協議詳解&#xff08;5&#xff09;——Python包命令&#xff1a;uv與uvx實戰 第13章 MCP協議詳解13.5 Python包命令&#xff1a;uv與uvx實戰13.5.1 uv核心亮點與常用命令1. uv介紹2. 安裝與項目管理3. 腳本與工具4. Python版本與pip接口 13.5.2 uv核心指令…

OD 算法題 B卷【求最小步數】

文章目錄 求最小步數 求最小步數 求從坐標零點到坐標點n的最小步數&#xff0c;一次只能沿著橫坐標軸向左或向右移動2或3&#xff1b;途經的坐標點可以為負數&#xff1b; 輸入描述: 坐標點n 輸出描述: 從坐標零點移動到坐標點n的最小步數 n在【1,10^9】 示例1 輸入&#xf…

Elasticsearch 集群升級實戰指引—7.x 升級到 8.x

升級Elasticsearch集群從7.x到8.x是一項復雜且關鍵的任務&#xff0c;涉及重大版本變更&#xff08;如API調整、配置變更、安全功能強制啟用等&#xff09;&#xff0c;可能影響集群的性能和穩定性。結合您提到的業務量增長導致索引寫入變慢的問題&#xff0c;本指引不僅提供詳…

JWT學習總結

文章目錄 前置知識Authorization頭部和 CookieCRSF攻擊 JWT概念JWT認證流程使用Springboot整合JWTJwtUtil JWT案例控制器JWT攔截器注冊攔截器結果 session VS Jwt 前置知識 Authorization頭部和 Cookie Authorization 頭部和 Cookie 是 HTTP 協議中兩種不同的身份認證 / 信息…

阿里云消息隊列 Apache RocketMQ 創新論文入選頂會 ACM FSE 2025

近日&#xff0c;由阿里云消息團隊發表的 Apache RocketMQ 創新論文被 CCF-A 類軟件工程頂級會議 FSE 2025 Industry Track 錄用。 ACM FSE&#xff08;The ACM International Conference on the Foundations of Software Engineering&#xff09;是享有盛譽的國際學術會議&…

定制WordPress管理后臺

WordPress作為全球最流行的建站工具&#xff0c;因其靈活性和易用性受到廣泛歡迎。許多服務器提供商都支持一鍵安裝WordPress&#xff0c;例如Hostease&#xff0c;使新手用戶也能輕松搭建屬于自己的網站。然而&#xff0c;后臺的默認設置可能無法完全滿足不同用戶的需求。定制…

REST API設計與Swagger:構建高效、易用的Web服務

引言 在現代Web開發中&#xff0c;REST API已成為不同系統間通信的標準方式。一個設計良好的REST API不僅能提高開發效率&#xff0c;還能改善用戶體驗。而Swagger&#xff08;現稱為OpenAPI&#xff09;作為API文檔和測試的強大工具&#xff0c;已經成為API開發中不可或缺的一…

一個非對齊訪問的問題

1、引言 最近在編寫代碼時&#xff0c;出現了這樣一個 bug。程序一跑&#xff0c;系統就崩潰了&#xff0c;報錯是 bus error。 目標平臺&#xff1a;ARM32 最終定位到出錯的代碼片段&#xff1a; *((uint32_t *)ptr) id;這里的 ptr 是一個非 4 字節對齊的地址&#xff01;&a…

【構造】P8976 「DTOI-4」排列|普及+

本文涉及知識點 構造 P8976 「DTOI-4」排列 題目背景 Update on 2023.2.1&#xff1a;新增一組針對 yuanjiabao 的 Hack 數據&#xff0c;放置于 #21。 Update on 2023.2.2&#xff1a;新增一組針對 CourtesyWei 和 bizhidaojiaosha 的 Hack 數據&#xff0c;放置于 #22。…