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的更多相关文章

  1. RAII惯用法详解

    [1]什么是RAII惯用法? RAII是Resource Acquisition Is Initialization的缩写,意为“资源获取即初始化”. 它是C++之父Bjarne Stroustrup ...

  2. [转]编译防火墙——C++的Pimpl惯用法解析

    impl(pointer to implementation, 指向实现的指针)是一种常用的,用来对“类的接口与实现”进行解耦的方法.这个技巧可以避免在头文件中暴露私有细节(见下图1),因此是促进AP ...

  3. WPF - 绑定及惯用法(一)

    写在前面:这仍然是一些没有经过严格审阅的文字.虽然我的确执行了初稿.复稿以及审阅等一系列用以保证文章质量的方法,但是仍然担心其中是否有错误.希望您能帮助指出,以在下一次我在版本更新时进行修正.所有的错 ...

  4. 编译防火墙——C++的Pimpl惯用法解析

    http://blog.csdn.net/lihao21/article/details/47610309 Pimpl(pointer to implementation, 指向实现的指针)是一种常用 ...

  5. java惯用法转载

    目录 实现: equals() hashCode() compareTo() clone() 应用: StringBuilder/StringBuffer Random.nextInt(int) It ...

  6. Notepad++ v5.5以上 惯用法教程

    注:本文中为注明为自定义快捷键的,均为notepad++的默认快捷键. 0.  关闭标签页 UltraEdit是双击窗口就可以关闭,Notepad++双击不能关闭,右键只能关闭非当前标签页,那怎么办呢 ...

  7. c++ RAII 资源管理就是初始化

    RAII:(Resource Acquisition Is Initialization),也就是“资源获取就是初始化”,是C++语言的一种管理资源.避免泄漏的惯用法.C++标准保证任何情况下,已构造 ...

  8. C++ 资源管理之 RAII

    RAII,它是“Resource Acquisition Is Initialization”的首字母缩写.也称为“资源获取就是初始化”,是c++等编程语言常用的管理资源.避免内存泄露的方法.它保证在 ...

  9. C++之RAII惯用法

    http://blog.csdn.net/hunter8777/article/details/6327704 C++中的RAII全称是“Resource acquisition is initial ...

  10. C++ RAII 与 ScopeGuard

    C++ RAII 与 ScopeGuard RAII机制 RAII(Resource Acquisition Is Initialization),也就是“资源获取就是初始化”,是C++语言的一种管理 ...

随机推荐

  1. 其它——ASCII码,Unicode和UTF-8编码

    文章目录 一 ASCII码 二 非ASCII编码 三 Unicode 3.1 Unicode存在的问题 3.2 它们造成的结果是 四 UTF-8 4.1 UTF-8 特点 4.2 UTF-8 的编码规 ...

  2. 【题解】《PTA-Python程序设计》题目集分享

    第1章-1 从键盘输入两个数,求它们的和并输出 (30 分) 本题目要求读入2个整数A和B,然后输出它们的和. 输入格式: 在一行中给出一个被加数在另一行中给出一个加数 输出格式: 在一行中输出和值. ...

  3. Mind2Web: Towards a Generalist Agent for the Web 论文解读

    主页:https://osu-nlp-group.github.io/Mind2Web 训练集:https://huggingface.co/datasets/osunlp/Mind2Web 概要 本 ...

  4. linux- 挂载本地iso,配置本地yum

    ------------------------------------ 关于centos8安装vm-tools: workstation部署centos8之后,不需要单独安装vm-tools,系统已 ...

  5. 麒麟系统开发笔记(十三):在国产麒麟系统上编译OSG库、搭建基础开发环境和移植测试Demo

    前言   在国产麒麟系统上实现C++三维仿真,使用OSG技术,其他基于web的技术也是可以但是交互上鼠标拽托等交互相对差一些,所以这块需要斟酌选择到底是何种技术来取舍.  本篇在厂家指定的麒麟系统上编 ...

  6. CSP 2023 游记

    省流:把 #define int long long 写在快读下面,找到答案了不 break. Day -1 手速大赛很有趣,但有人不认识 Aigony 我不说是谁. Day 0 睡大觉,给小朋友讲考 ...

  7. RLChina理论三:强化学习基础

    强化学习基础 马尔可夫决策过程就是在,环境自发做出转变,是个随波逐流的过程,At是智能体的行动,在St环境状态下加入At动作,c才进入下个状态S(t+1),即环境有自己的变化,也加入了智能体的决策. ...

  8. animate.css 动画种类(详细)

    作者:WangMin 格言:努力做好自己喜欢的每一件事 以下为各种动画类型包含的不同动画效果类,仅供参考.具体可查看animate.css 官网. bounce 弹跳 2. flash 闪烁 3. p ...

  9. Go类型嵌入介绍和使用类型嵌入模拟实现“继承”

    Go类型嵌入介绍和使用类型嵌入模拟实现"继承" 目录 Go类型嵌入介绍和使用类型嵌入模拟实现"继承" 一.独立的自定义类型 二.继承 三.类型嵌入 3.1 什么 ...

  10. CodeDesk-一个新款跨平台桌面开发框架

    CodeDesk 的灵感来自 Electron和Photino.这是一个基于 .NET 的开源项目. CodeDesk 的目标是使开发人员能够在跨平台的本机应用程序中使用 Web UI(HTML.Ja ...