C++RAII机制

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

什么是RAII?

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

为什么要使用RAII?

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








一个最简单的例子:

#include 
  
    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 
  
    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< 
    
  

上面这个例子没有多大的实际意义,只是为了说明RAII的机制问题。下面说一个具有实际意义的例子:

template 
  
    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,其会在构造函数的时候提供已锁的互斥量,并在析构的时候进行解锁,从而保证了一个已锁的互斥量总是会被正确的解锁。上面的代码正式

>头文件中的源码,其中还使用到很多C++11的特性,比如delete/noexcept等,有兴趣的同学可以查一下。

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/207871.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午12:54
下一篇 2026年3月19日 下午12:54


相关推荐

  • pstack 与 strace[通俗易懂]

    pstack 与 strace[通俗易懂]strace  strace是可以记录程序系统调用的一个工具,它可以记录该程序系统调用的各个延时情况。-c统计每一系统调用的所执行的时间,次数和出错的次数等.-d输出strace关于标准错误的调试信息.-f跟踪由fork调用所产生的子进程.-ff如果提供-ofilename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号.-F尝试跟踪vf…

    2025年11月17日
    6
  • 自旋锁和互斥锁的区别

    自旋锁和互斥锁的区别自旋锁和互斥锁的区别 POSIXthreads 简称 Pthreads 是在多核平台上进行并行编程的一套 API 线程同步是并行编程中非常重要的通讯手段 其中最典型的应用就是用 Pthreads 提供的锁机制 lock 来对多个线程之间的共享临界区 CriticalSect 进行保护 另一种常用的同步机制是 barrier Pthreads 提供了多种锁机制 Mutex 互斥量 pthread mutex t Spinlock 自旋锁 pthread spin t Conditio

    2026年3月19日
    2
  • 键盘记录器,可截获到 QQ 的密码「建议收藏」

    键盘记录器,可截获到 QQ 的密码「建议收藏」虽然QQ 的密码框经过了特殊的处理,但是通过一些特殊手段仍然可以得到输入过程中键盘输入的内容。代码仅供娱乐使用!

    2022年7月20日
    20
  • Layui treeTable相关

    Layui treeTable相关layui官网是没有treeTable这个功能的,需要下载额外的插件实现,幸运的是有符合layui风格的treeTable插件,此篇围绕树状表格讲述。treeTable官网指路:https://gitee.com/whvse/treetable-lay/wikis/pages下载有Gitee账号官网TreeTable资源下载路径:https://gitee.com/whvse/treetable-lay无Gitee账号导入treeTable的导入方式和layui其他组件一样,都是通过layui

    2022年5月6日
    57
  • LINUX 命令 之 zip 解压缩

    LINUX 命令 之 zip 解压缩1.zip命令zip-rmyfile.zip./*将当前目录下的所有文件和文件夹全部压缩成myfile.zip文件,-r表示递归压缩子目录下所有文件.2.unzip命令unzip-o-d/home/sunnymyfile.zip把myfile.zip文件解压到/home/sunny/-o:不提示的情况下覆盖文件;-d:-d/home/sunny指明将文件解压缩到/…

    2022年6月3日
    35
  • 智谱终于发布GLM-4.5技术报告,从预训练到后训练,细节大公开

    智谱终于发布GLM-4.5技术报告,从预训练到后训练,细节大公开

    2026年3月12日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号