【C/C++】RAII,Stack-only对象和Heap-only对象

RAII 详解

什么是 RAII

Resource Acquisition Is Initialization(资源获取即初始化)

核心思想:把资源的生命周期绑定到对象的生命周期

  • 构造函数获取资源
  • 析构函数释放资源
  • 对象销毁时,资源自动释放

FileHandler 示例

没有 RAII 的写法

voidprocess(){FILE*f=fopen("data.txt","r");if(some_error){return;// 忘记 fclose,文件泄漏!}do_something();// 如果抛异常,也泄漏!fclose(f);}

问题:每个退出路径都要手动关闭文件,容易遗漏。

RAII 版本

// file_handler.hpp#pragmaonce#include<cstdio>#include<stdexcept>#include<string>classFileHandler{FILE*fp;public:// 构造时打开文件(获取资源)FileHandler(constchar*path,constchar*mode):fp(fopen(path,mode)){if(!fp){throwstd::runtime_error("Cannot open file: "+std::string(path));}}// 析构时关闭文件(释放资源)~FileHandler(){if(fp){fclose(fp);}}// 禁止拷贝(避免双重关闭)FileHandler(constFileHandler&)=delete;FileHandler&operator=(constFileHandler&)=delete;// 允许移动FileHandler(FileHandler&&other)noexcept:fp(other.fp){other.fp=nullptr;}FileHandler&operator=(FileHandler&&other)noexcept{if(this!=&other){if(fp)fclose(fp);fp=other.fp;other.fp=nullptr;}return*this;}// 使用文件FILE*get()const{returnfp;}size_tread(void*buf,size_t size){returnfread(buf,1,size,fp);}size_twrite(constvoid*buf,size_t size){returnfwrite(buf,1,size,fp);}};

使用方式

#include"file_handler.hpp"#include<iostream>voidprocess(){FileHandlerfile("data.txt","r");// 打开文件if(some_error){return;// 自动关闭!}do_something();// 异常也自动关闭!charbuf[1024];file.read(buf,sizeof(buf));}// 离开作用域,自动关闭intmain(){try{FileHandlerf1("input.txt","r");FileHandlerf2("output.txt","w");charbuf[4096];size_t n;while((n=f1.read(buf,sizeof(buf)))>0){f2.write(buf,n);}}catch(conststd::exception&e){std::cerr<<e.what()<<"\n";// f1, f2 已经自动关闭了}}

Stack Only 版本

强制 FileHandler 只能在栈上创建,确保 RAII 生效:

// file_handler_stack.hpp#pragmaonce#include<cstdio>#include<stdexcept>classFileHandler{FILE*fp;public:FileHandler(constchar*path,constchar*mode):fp(fopen(path,mode)){if(!fp)throwstd::runtime_error("Cannot open file");}~FileHandler(){if(fp)fclose(fp);}// 禁止拷贝FileHandler(constFileHandler&)=delete;FileHandler&operator=(constFileHandler&)=delete;// 禁止堆分配,强制栈上使用void*operatornew(size_t)=delete;void*operatornew[](size_t)=delete;FILE*get()const{returnfp;}};

使用:

voidprocess(){FileHandlerfile("data.txt","r");// ✓ 栈上,自动管理// FileHandler* p = new FileHandler(); // ✗ 编译错误}

为什么要 Stack Only?防止这种情况:

voidbad(){FileHandler*p=newFileHandler("data.txt","r");// 忘记 delete p,文件永远不会关闭}

Heap Only 版本

有时需要共享文件句柄,使用引用计数:

// file_handler_heap.hpp#pragmaonce#include<cstdio>#include<memory>#include<stdexcept>classFileHandler{FILE*fp;// 私有构造/析构,只能通过 create() 创建FileHandler(constchar*path,constchar*mode):fp(fopen(path,mode)){if(!fp)throwstd::runtime_error("Cannot open file");}~FileHandler(){if(fp)fclose(fp);}public:// 工厂方法,返回 shared_ptrstaticstd::shared_ptr<FileHandler>create(constchar*path,constchar*mode){autop=newFileHandler(path,mode);// lambda 在成员函数内,可以访问私有析构returnstd::shared_ptr<FileHandler>(p,[](FileHandler*f){deletef;});}FILE*get()const{returnfp;}};

使用:

voidprocess(){// FileHandler f("data.txt", "r"); // ✗ 编译错误autofile=FileHandler::create("data.txt","r");// ✓autofile2=file;// 共享所有权,引用计数 = 2// 传给其他函数/线程async_read(file);}// 引用计数归零时自动关闭

三种方式对比

┌─────────────────┬──────────────────┬──────────────────┬──────────────────┐ │ │ 普通 RAII │ Stack Only │ Heap Only │ ├─────────────────┼──────────────────┼──────────────────┼──────────────────┤ │ 栈上创建 │ ✓ │ ✓ │ ✗ │ ├─────────────────┼──────────────────┼──────────────────┼──────────────────┤ │ 堆上创建 │ ✓ │ ✗ │ ✓ │ ├─────────────────┼──────────────────┼──────────────────┼──────────────────┤ │ 生命周期 │ 作用域或手动 │ 作用域 │ 引用计数 │ ├─────────────────┼──────────────────┼──────────────────┼──────────────────┤ │ 共享所有权 │ 需要 shared_ptr │ ✗ │ ✓ (内置) │ ├─────────────────┼──────────────────┼──────────────────┼──────────────────┤ │ 适用场景 │ 通用 │ 局部资源管理 │ 跨作用域/线程共享 │ └─────────────────┴──────────────────┴──────────────────┴──────────────────┘

总结

┌────────────────────────────────────────────────────────┐ │ RAII 核心 │ ├────────────────────────────────────────────────────────┤ │ │ │ 构造 = 获取资源 │ │ 析构 = 释放资源 │ │ 对象死亡 = 资源释放 │ │ │ ├────────────────────────────────────────────────────────┤ │ 好处 │ ├────────────────────────────────────────────────────────┤ │ │ │ • 不会忘记释放 │ │ • 异常安全 │ │ • 代码简洁 │ │ │ ├────────────────────────────────────────────────────────┤ │ 选择指南 │ ├────────────────────────────────────────────────────────┤ │ │ │ 局部使用 → Stack Only │ │ 需要共享 → Heap Only + shared_ptr │ │ 不确定 → 普通 RAII │ │ │ └────────────────────────────────────────────────────────┘

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1125296.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2026必备!8个AI论文写作软件,继续教育学生轻松搞定论文格式规范!

2026必备&#xff01;8个AI论文写作软件&#xff0c;继续教育学生轻松搞定论文格式规范&#xff01; AI 工具助力论文写作&#xff0c;高效又省心 在当今信息化时代&#xff0c;继续教育学生面临着越来越高的学术要求。无论是撰写论文还是完成各类研究任务&#xff0c;如何确保…

【开题答辩全过程】以 旅游直通车服务为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

基于Spring Boot的装饰工程管理系统(11653)

有需要的同学&#xff0c;源代码和配套文档领取&#xff0c;加文章最下方的名片哦 一、项目演示 项目演示视频 二、资料介绍 完整源代码&#xff08;前后端源代码SQL脚本&#xff09;配套文档&#xff08;LWPPT开题报告&#xff09;远程调试控屏包运行 三、技术介绍 Java…

全网最全专科生必备TOP8 AI论文网站测评

全网最全专科生必备TOP8 AI论文网站测评 2026年专科生必备AI论文写作工具测评 随着人工智能技术的不断发展&#xff0c;越来越多的专科生开始借助AI工具提升论文写作效率。然而&#xff0c;面对市场上琳琅满目的AI写作平台&#xff0c;如何选择真正适合自己需求的产品成为一大难…

AI Agent在智能保险定价中的角色

AI Agent在智能保险定价中的角色 关键词:AI Agent、智能保险定价、风险评估、数据处理、决策优化 摘要:本文深入探讨了AI Agent在智能保险定价中的角色。首先介绍了研究的背景,包括目的、预期读者等内容。接着阐述了AI Agent和智能保险定价的核心概念及两者之间的联系,通过…

springboot健身房管理系统(11654)

有需要的同学&#xff0c;源代码和配套文档领取&#xff0c;加文章最下方的名片哦 一、项目演示 项目演示视频 二、资料介绍 完整源代码&#xff08;前后端源代码SQL脚本&#xff09;配套文档&#xff08;LWPPT开题报告&#xff09;远程调试控屏包运行 三、技术介绍 Java…

学长亲荐!继续教育必备TOP8 AI论文平台测评

学长亲荐&#xff01;继续教育必备TOP8 AI论文平台测评 一、不同维度核心推荐&#xff1a;8款AI工具各有所长 在继续教育的学习过程中&#xff0c;学术写作是一个不可或缺的环节&#xff0c;涵盖开题、初稿、查重、降重、排版等多个阶段。每种AI工具都有其独特的优势和适用场景…

audio2face mh_arkit_mapping_pose_A2F 不兼容

配置audio2face 是 mh_arkit_mapping_pose_A2F 不兼容怎么办如果你不想改 JSON 或者改映射太麻烦&#xff1a;用 Audio2Face 输出动画数据流&#xff08;gRPC / Python&#xff09;在 UE 中用 Control Rig / Morph Target 接收 A2F 输出数据可以 直接驱动任何自定义角色优点&am…

springboot智能学习平台系统(11655)

有需要的同学&#xff0c;源代码和配套文档领取&#xff0c;加文章最下方的名片哦 一、项目演示 项目演示视频 二、资料介绍 完整源代码&#xff08;前后端源代码SQL脚本&#xff09;配套文档&#xff08;LWPPT开题报告&#xff09;远程调试控屏包运行 三、技术介绍 Java…

两阶段目标检测的边框回归(学习记录)

两阶段目标检测:分两步&#xff1a;1. 第一步&#xff1a;生成候选区域&#xff08;可能包含目标的框&#xff09;2. 第二步&#xff1a;对候选区域做分类 边框回归。分类就是判断候选框是否包含目标&#xff0c;不包含就是背景。边框回归就是使得包含目标的边框靠近真实框。一…

AI智能体改变材料研发:7个案例,架构师的创新思路

AI智能体改变材料研发&#xff1a;7个案例&#xff0c;架构师的创新思路——技术博客文章 下面是根据用户输入的文章主题“AI智能体改变材料研发&#xff1a;7个案例&#xff0c;架构师的创新思路”撰写的一篇技术博客文章。文章采用Markdown格式&#xff0c;内容包括标题选项、…

基于springboot的疾病防控综合系统的设计与实现(11651)

有需要的同学&#xff0c;源代码和配套文档领取&#xff0c;加文章最下方的名片哦 一、项目演示 项目演示视频 二、资料介绍 完整源代码&#xff08;前后端源代码SQL脚本&#xff09;配套文档&#xff08;LWPPT开题报告&#xff09;远程调试控屏包运行 三、技术介绍 Java…

互联网大厂Java工程师面试实战:严肃面试官与搞笑谢飞机的技术对话

互联网大厂Java工程师面试实战&#xff1a;严肃面试官与搞笑谢飞机的技术对话 在互联网大厂的Java工程师面试中&#xff0c;技术深度和业务场景理解至关重要。本文通过一场模拟面试对话&#xff0c;展现严肃面试官如何循序渐进地提问&#xff0c;以及搞笑程序员谢飞机如何应答…

c盘应用程序怎么转移到d盘?无需重装,一键帮你迁移!

我们都知道C盘容易变满&#xff0c;但还是有很多人不好好管理&#xff0c;总是把应用程序下载到里面&#xff0c;让本就不足的空间“雪上加霜”。这时你可能会想到转移应用程序&#xff0c;给C盘“减负”。那么&#xff0c;c盘应用程序怎么转移到d盘&#xff1f;如果你不知道正…

企业估值中的量子加密通信卫星网络评估

企业估值中的量子加密通信卫星网络评估关键词&#xff1a;企业估值、量子加密通信、卫星网络、评估方法、技术原理摘要&#xff1a;本文聚焦于企业估值中量子加密通信卫星网络的评估。首先介绍了相关背景&#xff0c;包括目的范围、预期读者等内容。接着深入探讨量子加密通信卫…

论文降AI干货汇总:实测这几款免费降ai率工具,降ai率从80%到10%的保姆级教程!

宝子们&#xff0c;这一篇真的是救命干货&#xff0c;建议先点赞收藏&#xff0c;不然答辩前找不到真的会哭死&#xff01;&#x1f62d; 最近好多家人们在后台私信我&#xff0c;说论文查重都要被逼疯了。特别是学校现在严查AIGC&#xff0c;看着查重报告上那个鲜红的“88%”…

数据建模在大数据社交网络分析中的应用

数据建模在大数据社交网络分析中的应用&#xff1a;从理论到实践的完整指南 副标题&#xff1a;如何用图模型、社区检测与影响力预测解决真实场景问题 摘要/引言 社交网络已成为人类生活的核心场景——从微信的13亿月活用户到Twitter的5亿月活&#xff0c;每天产生的10TB级社…

asferror.dll文件丢失找不到 打不开问题 免费下载方法分享

在使用电脑系统时经常会出现丢失找不到某些文件的情况&#xff0c;由于很多常用软件都是采用 Microsoft Visual Studio 编写的&#xff0c;所以这类软件的运行需要依赖微软Visual C运行库&#xff0c;比如像 QQ、迅雷、Adobe 软件等等&#xff0c;如果没有安装VC运行库或者安装…

魔法打败魔法?这6款超强ai降ai软件,这才是真正的降ai率工具,实测3分钟让文章回归低AI率,安全过检测!

你的论文是不是AI率超高&#xff1f;一查降ai率结果80%以上&#xff1f; 别急&#xff0c;这种情况很多人遇到过。 用AI工具写论文确实快&#xff0c;但“AI味”太浓就容易翻车。 今天我就来分享几款自己用过、真心能打的ai降ai工具&#xff0c;从免费降ai率工具到专业级都涵…

互联网大厂Java面试三轮深度解析:面试官与程序员谢飞机的技术对话

互联网大厂Java面试三轮深度解析&#xff1a;面试官与程序员谢飞机的技术对话 前言 很多同学都希望成功进入互联网大厂成为 Java 工程师&#xff0c;本文以三轮面试场景为主线&#xff0c;展现一位严肃面试官与一位幽默搞笑程序员谢飞机之间的精彩对答。内容涵盖 Java 核心技…