最近一直在碰到这个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. Java Timer 定时器的使用
  2. 第十六界智能车竞赛:这问题怎么越来越多了呢?
  3. status_code想要得到302却得到200_曼联华裔小妖接尤文3.5万周薪合同,签约费200万!意甲要挖空曼联...
  4. HFSS中的求解类型(Solution Type)
  5. atmega8 例程:T1定时器 CTC模式 方波输出
  6. 一起学习C语言:数组(三)
  7. 关于深度学习编译器,这些知识你需要了解一下
  8. linux hadoop namenode_HADOOP_HDFS伪分布式安装步骤
  9. 再看产业地图及《中国2010-2011产业地图》书评
  10. 转载 WHO OWNS THE MOST SERVERS ?
  11. Clojure 学习入门(14)- 循环控制
  12. unity 模型销毁_Unity GameObject 销毁(Destroy)后的几种状态
  13. mysql centos_centos7mysql安装
  14. 风控模型面试问题汇总
  15. IEEE1588工业以太网交换机
  16. python 批量下载种子_批量下载btbbt种子
  17. 开始起飞-golang编码技巧分享--Dave Cheney博客读后整理
  18. Arduino 点灯实验
  19. html、css、vue、js在VsCode中代码格式化(代码自动调准为标准格式)
  20. 大数据------维度表,事实表

热门文章

  1. SpringBoot 2.6.* 整合springfox 3.0报错问题解决
  2. 高仿网易云音乐(vue实战项目)
  3. 软件测试基础-测试用例设计方法(等价类+边界值)
  4. 如何把pdf转换成word转换器在线
  5. 周末重温:我害怕阅读的人
  6. 路径规划算法1.1图搜索算法——可视图法
  7. html写出日出,描写日出的优美语句
  8. 硅光集成类光组件——模场转换MFD FA光纤阵列
  9. python svm核函数_机器学习算法实践-SVM核函数和软间隔
  10. 13.flowable 待办任务列表查询