C++ 惯用法之 RAII
RAII(Resource Acquisition Is Initialization)资源获取即初始化,是 C++ 中最基本、应用最广范的惯用法(idiom)之一。
RAII 的基本思想是通过构造/析构函数,对资源的获取/释放进行封装,然后借助局部对象的自动生命周期来管理资源。使用 RAII 可以让用户无需手动管理资源的获取/释放,减少出错的机会。不仅如此,RAII 还是异常安全的:即使获取资源后,在使用资源的过程中抛出异常,也可以自动释放,避免资源泄露。
C++ 标准库里面有很多 RAII 的例子,如 unique_ptr、lock_guard、fstream、string 以及 vector 等各类容器。我们在实现自己的类时,也要尽量遵循 RAII。
一些例子
C++ 核心指南 R.1: 通过资源句柄和 RAII 自动管理资源
// BAD
void send(X* x, string_view destination)
{
auto port = open_port(destination);
my_mutex.lock();
// ...
send(port, x);
// ...
// 在此之前一旦函数提前返回/抛出异常,将导致资源泄露!
my_mutex.unlock();
close_port(port);
delete x;
}
// GOOD
void send(unique_ptr<X> x, string_view destination)
{
Port port{destination};
lock_guard<mutex> guard{my_mutex};
// ...
send(port, x);
// ...
} // 自动释放 my_mutex、关闭 port,并删除 x 指向的对象
C++ 核心指南 CP.20:使用 RAII,不要直接用 lock()/unlock()
mutex mtx;
// BAD
void do_stuff()
{
mtx.lock();
// ...
// 如果抛出异常,导致 mtx 不被释放!
mtx.unlock();
}
// GOOD
void do_stuff()
{
unique_lock<mutex> lck {mtx};
// 即使抛出异常, mtx 会自动释放!
}
C++ 核心指南 P.8:不要泄露任何资源
// BAD
void f(char* name)
{
FILE* input = fopen(name, "r");
// ...
// bad: 如果 something == true,导致文件句柄泄漏!
if (something) return;
// ...
// 如果在此之前的代码抛出异常,也会导致文件句柄泄露!
fclose(input);
}
// GOOD
void f(char* name)
{
ifstream input {name};
// ...
if (something) return;
// ...
// 只要离开函数作用域,自动释放文件句柄
}
C++ 惯用法之 RAII的更多相关文章
- RAII惯用法详解
[1]什么是RAII惯用法? RAII是Resource Acquisition Is Initialization的缩写,意为“资源获取即初始化”. 它是C++之父Bjarne Stroustrup ...
- [转]编译防火墙——C++的Pimpl惯用法解析
impl(pointer to implementation, 指向实现的指针)是一种常用的,用来对“类的接口与实现”进行解耦的方法.这个技巧可以避免在头文件中暴露私有细节(见下图1),因此是促进AP ...
- WPF - 绑定及惯用法(一)
写在前面:这仍然是一些没有经过严格审阅的文字.虽然我的确执行了初稿.复稿以及审阅等一系列用以保证文章质量的方法,但是仍然担心其中是否有错误.希望您能帮助指出,以在下一次我在版本更新时进行修正.所有的错 ...
- 编译防火墙——C++的Pimpl惯用法解析
http://blog.csdn.net/lihao21/article/details/47610309 Pimpl(pointer to implementation, 指向实现的指针)是一种常用 ...
- java惯用法转载
目录 实现: equals() hashCode() compareTo() clone() 应用: StringBuilder/StringBuffer Random.nextInt(int) It ...
- Notepad++ v5.5以上 惯用法教程
注:本文中为注明为自定义快捷键的,均为notepad++的默认快捷键. 0. 关闭标签页 UltraEdit是双击窗口就可以关闭,Notepad++双击不能关闭,右键只能关闭非当前标签页,那怎么办呢 ...
- c++ RAII 资源管理就是初始化
RAII:(Resource Acquisition Is Initialization),也就是“资源获取就是初始化”,是C++语言的一种管理资源.避免泄漏的惯用法.C++标准保证任何情况下,已构造 ...
- C++ 资源管理之 RAII
RAII,它是“Resource Acquisition Is Initialization”的首字母缩写.也称为“资源获取就是初始化”,是c++等编程语言常用的管理资源.避免内存泄露的方法.它保证在 ...
- C++之RAII惯用法
http://blog.csdn.net/hunter8777/article/details/6327704 C++中的RAII全称是“Resource acquisition is initial ...
- C++ RAII 与 ScopeGuard
C++ RAII 与 ScopeGuard RAII机制 RAII(Resource Acquisition Is Initialization),也就是“资源获取就是初始化”,是C++语言的一种管理 ...
随机推荐
- bash: accelerate: command not found
py AIGC Stable Diffusion文生图Lora模型微调实现虚拟上装详情 实验手册 实验报告 3. 安装Diffusers 进入PAI-DSW开发环境. 登录PAI控制台. ...
- Excel--比较两列数据的异同
首先得到的数据分为两列,两种类型.由于在网站上搜索的时候,网站的"特殊性"会将000638-32-4 前面的0全部去掉.变成了638-32-4.基于得到了两列稍有不同的数据.由于人 ...
- 麒麟系统开发笔记(十三):在国产麒麟系统上编译OSG库、搭建基础开发环境和移植测试Demo
前言 在国产麒麟系统上实现C++三维仿真,使用OSG技术,其他基于web的技术也是可以但是交互上鼠标拽托等交互相对差一些,所以这块需要斟酌选择到底是何种技术来取舍. 本篇在厂家指定的麒麟系统上编 ...
- 一篇了解springboot3请求参数种类及接口测试
SpringBoot3数据请求: 原始数据请求: //原始方式 @RequestMapping("/simpleParam") public String simpleParam( ...
- Ubuntu22.04 rc-local 配置开机自启动脚本
1. rc-local服务简介Linux中的rc-local服务是一个开机自动启动的,调用开发人员或系统管理员编写的可执行脚本或命令的,它的启动顺序是在系统所有服务加载完成之后执行. ubuntu22 ...
- influxdb报错:cache-max-memory-size exceeded
转载请注明出处: influxdb报错日志: 该错误信息表示 InfluxDB 引擎超过了缓存最大内存大小.这意味着 InfluxDB 的缓存使用量超出了配置的限制. 要解决此问题,可以采取以下步骤来 ...
- [Python急救站课程]等边三角形的绘制
等边三角形的绘制 from turtle import * penup() fd(-50) pendown() pensize(25) seth(60) fd(100) seth(-60) fd(10 ...
- 算法训练 递归 s01串
问题描述 s01串初始为"0" 按以下方式变换 0变1,1变01 输入格式 1个整数(0~19) 输出格式 n次变换后s01串 样例输入 3 样例输出 101 数据规模和约定 0~ ...
- 【VMware vCenter】使用cmsso-util命令进行链接、删除、修改多个vCenter Server(VCSA)的SSO域。
VMware vCenter Server 支持新安装的时候选择将vCenter SSO域加入到另外一个现有的SSO域中,同时也支持使用cmsso-util命令将现有的两个或多个vCenter SSO ...
- Educational Codeforces Round 56 (Rated for Div. 2) G题(线段树,曼哈顿距离)
题目传送门 以二维为例,二维下两点间的曼哈顿距离最大值为\(max(|x_i-x_j| + |y_i-y_j|)\),可以通过枚举坐标符号正负来去掉绝对值.即\(max(x_i-x_j+y_i-y_j ...