首页 > 编程语言 >C++ 惯用法之 RAII

C++ 惯用法之 RAII

时间:2023-07-02 17:57:06浏览次数:41  
标签:... mtx 惯用 RAII void C++ port

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;
    // ...
    // 只要离开函数作用域,自动释放文件句柄
}

标签:...,mtx,惯用,RAII,void,C++,port
From: https://www.cnblogs.com/tengzijian/p/17521080.html

相关文章

  • C/C++订餐管理系统[2023-07-02]
    C/C++订餐管理系统[2023-07-02]1、订餐管理系统要求实现饭店的订餐信息管理,包括菜单管理、订单管理、统计分析。实现菜单信息(菜号、菜名、价格、成本)的增删改查,实现订单管理(订单号、就餐人数、下单时间、订单总价、订单包含的所有菜品(菜号、数量))。系统功能包括以下方......
  • C++ <iomanip>头文件
    `iomanip`是C++标准库中提供了对输入输出流的输入输出格式进行控制的头文件。它定义了一些操纵符(manipulator),可以用于设置输出流的格式。下面是一些常用的`iomanip`操纵符的详细说明:setw(n):设置输出字段的宽度为n个字符,默认为右对齐。例如:#include<iostream>#include<i......
  • C++ 核心指南之资源管理(下)—— 智能指针最佳实践
    C++核心指南(C++CoreGuidelines)是由BjarneStroustrup、HerbSutter等顶尖C+专家创建的一份C++指南、规则及最佳实践。旨在帮助大家正确、高效地使用“现代C++”。这份指南侧重于接口、资源管理、内存管理、并发等High-level主题。遵循这些规则可以最大程度地保证静......
  • C++面试八股文:技术勘误
    不知不觉,《C++面试八股文》已经更新30篇了,这是我第一次写技术博客,由于个人能力有限,出现了不少纰漏,在此向各位读者小伙伴们致歉。为了不误导更多的小伙伴,以后会不定期的出勘误文章,请各位小伙伴留意。在《C++面试八股文:C++中,设计一个类要注意哪些东西?》一文中,#include<iostream>......
  • 【C++】打开C++大门,踏入C++世界
    ☑️前言......
  • C++面试八股文:std::vector和std::list,如何选择?
    C++面试八股文:std::vector和std::list,如何选择?某日二师兄参加XXX科技公司的C++工程师开发岗位第24面:面试官:list用过吗?二师兄:嗯,用过。面试官:请讲一下list的实现原理。二师兄:std::list被称为双向链表,和C中手写双向链表本质上没有大的区别。list对象中有两个指针,一个指向......
  • 利用ccache提高c++编译速度
    首先安装ccache:sudoaptinstallccache然后在cmake文件中添加如下代码即可:find_program(CCACHE_FOUNDccache)if(CCACHE_FOUND)set_property(GLOBALPROPERTYRULE_LAUNCH_COMPILEccache)set_property(GLOBALPROPERTYRULE_LAUNCH_LINKccache)endi......
  • C/C++《数据结构课程设计》题目[2023-07-01]
    C/C++《数据结构课程设计》题目[2023-07-01]《数据结构课程设计》题目一、【大数四则运算】——线性表[习题描述]设计—个实现任意长的整数进行四则运算和幂次运算的演示程序。[基本要求]利用双向循环链表实现大数的存储,每个结点含一个整型变量。[实现提示]实现原理:任何一......
  • C++ 编程中的核心知识点
    const作用修饰变量,说明该变量不可以被改变;修饰指针,分为指向常量的指针(pointertoconst)和自身是常量的指针(常量指针,constpointer);修饰引用,指向常量的引用(referencetoconst),用于形参类型,即避免了拷贝,又避免了函数对值的修改;修饰成员函数,说明该成员函数内不能修改成员......
  • C++之future
    背景在C++多线程编程中,同步线程间的操作和结果通常是一个关键问题。C++11引入了std::future这一同步原语,用于表示异步操作的结果。本文将介绍C++中std::future的使用方法、优势以及与其他同步方法的对比。使用std::futurestd::future表示一个异步操作的结果,可以用于获取操作的......