最近一直在碰到这个RAII机制,但是似乎没搞清楚这啥意思。现在大概明白了,C++的RAII机制就是类似于C#或者Java的GC机制,垃圾回收。合理的回收系统资源,避免程序员大量的写重复的delete代码来手动回收。粗暴点将就是,靠类对象的作用域/生存期来管理资源。

转载于:https://blog.csdn.net/quinta_2018_01_09/article/details/93638251


什么是RAII?

RAII是Resource Acquisition Is Initialization(wiki上面翻译成 “资源获取就是初始化”)的简称,是C++语言的一种管理资源、避免泄漏的惯用法。利用的就是C++构造的对象最终会被销毁的原则。RAII的做法是使用一个对象,在其构造时获取对应的资源,在对象生命期内控制对资源的访问,使之始终保持有效,最后在对象析构的时候,释放构造时获取的资源。

为什么要使用RAII?

上面说到RAII是用来管理资源、避免资源泄漏的方法。那么,用了这么久了,也写了这么多程序了,口头上经常会说资源,那么资源是如何定义的?在计算机系统中,资源是数量有限且对系统正常运行具有一定作用的元素。比如:网络套接字、互斥锁、文件句柄和内存等等,它们属于系统资源。由于系统的资源是有限的,就好比自然界的石油,铁矿一样,不是取之不尽,用之不竭的,所以,我们在编程使用系统资源时,都必须遵循一个步骤:
1 申请资源;
2 使用资源;
3 释放资源。
第一步和第三步缺一不可,因为资源必须要申请才能使用的,使用完成以后,必须要释放,如果不释放的话,就会造成资源泄漏。

一个最简单的例子:

#include <iostream> using namespace std; int main() { int *testArray = new int [10]; // Here, you can use the array delete [] testArray; testArray = NULL ; return 0;
}
小结:

但是如果程序很复杂的时候,需要为所有的new 分配的内存delete掉,导致极度臃肿,效率下降,更可怕的是,程序的可理解性和可维护性明显降低了,当操作增多时,处理资源释放的代码就会越来越多,越来越乱。如果某一个操作发生了异常而导致释放资源的语句没有被调用,怎么办?这个时候,RAII机制就可以派上用场了。

如何使用RAII?

当我们在一个函数内部使用局部变量,当退出了这个局部变量的作用域时,这个变量也就别销毁了;当这个变量是类对象时,这个时候,就会自动调用这个类的析构函数,而这一切都是自动发生的,不要程序员显示的去调用完成。这个也太好了,RAII就是这样去完成的。

由于系统的资源不具有自动释放的功能,而C++中的类具有自动调用析构函数的功能。如果把资源用类进行封装起来,对资源操作都封装在类的内部,在析构函数中进行释放资源。当定义的局部变量的生命结束时,它的析构函数就会自动的被调用,如此,就不用程序员显示的去调用释放资源的操作了。

使用RAII 机制的代码:

#include <iostream>
using namespace std; class ArrayOperation
{
public : ArrayOperation() { m_Array = new int [10]; } void InitArray() { for (int i = 0; i < 10; ++i) { *(m_Array + i) = i; } } void ShowArray() { for (int i = 0; i <10; ++i) { cout<<m_Array[i]<<endl; } } ~ArrayOperation() { cout<< "~ArrayOperation is called" <<endl; if (m_Array != NULL ) { delete[] m_Array;  m_Array = NULL ; } } private : int *m_Array;
}; bool OperationA();
bool OperationB(); int main()
{ ArrayOperation arrayOp; arrayOp.InitArray(); arrayOp.ShowArray(); return 0;
}
上面这个例子没有多大的实际意义,只是为了说明RAII的机制问题。下面说一个具有实际意义的例子:
template<class... _Mutexes>class lock_guard{   // class with destructor that unlocks mutexes
public:explicit lock_guard(_Mutexes&... _Mtxes): _MyMutexes(_Mtxes...){ // construct and lock_STD lock(_Mtxes...);}lock_guard(_Mutexes&... _Mtxes, adopt_lock_t): _MyMutexes(_Mtxes...){    // construct but don't lock}~lock_guard() _NOEXCEPT{   // unlock all_For_each_tuple_element(_MyMutexes,[](auto& _Mutex) _NOEXCEPT { _Mutex.unlock(); });}lock_guard(const lock_guard&) = delete;lock_guard& operator=(const lock_guard&) = delete;
private:tuple<_Mutexes&...> _MyMutexes;};

在使用多线程时,经常会涉及到共享数据的问题,C++中通过实例化std::mutex创建互斥量,通过调用成员函数lock()进行上锁,unlock()进行解锁。不过这意味着必须记住在每个函数出口都要去调用unlock(),也包括异常的情况,这非常麻烦,而且不易管理。C++标准库为互斥量提供了一个RAII语法的模板类std::lock_guard,其会在构造函数的时候提供已锁的互斥量,并在析构的时候进行解锁,从而保证了一个已锁的互斥量总是会被正确的解锁。上面的代码正式<mutex>>头文件中的源码,其中还使用到很多C++11的特性,比如delete/noexcept等,有兴趣的同学可以查一下。

文章参考:https://www.jianshu.com/p/b7ffe79498be

C++ RAII机制相关推荐

  1. C++中的RAII机制

    什么是RAII? RAII是Resource Acquisition Is Initialization(wiki上面翻译成 "资源获取就是初始化")的简称,是C++语言的一种管理 ...

  2. C++之RAII机制

    1.什么是RAII? RAII(Resource Acquisition Is Initialization)机制是Bjarne Stroustrup首先提出的,也称直译为"资源获取就是初始 ...

  3. 【C++设计技巧】C++中的RAII机制

    随笔- 427  文章- 0  评论- 4 作者:gnuhpc  出处:http://www.cnblogs.com/gnuhpc/ 1.概念 Resource Acquisition Is Init ...

  4. C 多线程的互斥锁应用RAII机制

    什么是RAII机制 RAII是Resource Acquisition Is Initialization(翻译成 "资源获取即初始化")的简称,是C 语言的一种管理资源.避免资源 ...

  5. C++RAII机制(智能指针原理)

    原文详细整理 C++中的RAII机制 - 码到城攻RAII机制,是C++语言的一种管理资源.避免泄漏的惯用法https://www.codecomeon.com/posts/200/ 何为RAII R ...

  6. C++程序设计机制:RAII机制

    1.背景 C/C++程序开发中,管理堆上分配的内存容易出错,常见的就是内存泄漏.原则上,只要我们足够仔细,在每一次动态分配内存之后,使用完毕后,手动delete即可释放掉内存,可是这必然会加大我们的工 ...

  7. RAII机制原理分析

    本文转载自: https://blog.csdn.net/wozhengtao/article/details/52187484 前言 RAII的基本思想就是当对象的生命周期结束时,自动调用起析构函数 ...

  8. C++——RAII机制

    文章目录 我们知道,资源的使用一般经历三个步骤 a.获取资源 b.使用资源 c.销毁资源 资源的销毁往往是程序员经常忘记的一个环节,忘记销毁资源可能会造成内存泄露,怎么解决呢?--RAII RAII: ...

  9. C++高阶 RAII机制(以对象管理资源)

    文章目录 1.什么是RAII 2.RAII的原理 3.实例: 1.什么是RAII RAII(Resource Acquisition Is Initialization)是由c++之父Bjarne S ...

最新文章

  1. 【079】用代码来创建 Android 控件
  2. Nor 与Nand Flash 区别
  3. 今天悄悄的给你说几个HashCode的破事。
  4. 产品经理如何激发出新的创意
  5. MOS管的工作原理及常见的封装(看完必会)
  6. 开源纯C#工控网关+组态软件(四)上下位机通讯原理
  7. 国内首款全国产固态硬盘控制芯片发布
  8. android intent拍照,Android通过Intent方式调用相机拍照取得图片
  9. SSH-struts2的异常处理
  10. linux安装 wegt_linux 下安装wget
  11. Ps2021教程,如何在photoshop中调整建筑物透视效果?
  12. Spring结合马士兵视频的学习经验
  13. 大数据实验数据集何处来?
  14. 小甲鱼 C语言 22课指针和数组
  15. Oracle中的LOB字段解读
  16. 像素级图像融合常用方法
  17. Chrome 开发者工具 Initiator 面板单击后看不到 JavaScript 源代码的解决方法
  18. 移动端微信、QQ浏览器 web 用 rem 单位适配不生效问题
  19. 深大uooc学术道德与学术规范教育第九章
  20. fota 差分包_FOTA相关知识总结

热门文章

  1. 交通运输部印发《城市公共交通“十三五”发展纲要》
  2. 免费申请Office365教育版,免费5TOneDrive云盘(亲测可用)
  3. 重新定位svn地址的方法
  4. centOS7系统虚拟机节点的搭建
  5. Python 3.9.0 已经可以下载了,但不支持win7和更低的系统版本!
  6. Android 动画 Animator 家族使用指南
  7. 两根网线可以直接连接吗?
  8. python 公主连接,公主连接打金牛座四王有什么小技巧吗 一阶段四王图文攻略
  9. python grad_在Python中实现Adagrad
  10. Ora 28547连接服务器失败,可能是Oracle Net 管理错误问题详解(可能是最简单的)