RAII机制介绍

RAII机制介绍RAII 机制介绍 RAII 全程为 ResourceAcqu 资源获取即初始化 RAII 是 C 语法体系中的一种常用的合理管理资源避免出现内存泄漏的常用方法 以对象管理资源 利用的就是 C 构造的对象最终会被对象的析构函数销毁的原则 RAII 的做法是使用一个对象 在其构造时获取对应的资源 在对象生命期内控制对资源的访问 使之始终保持有效 最后在对象析构的时候 释放构造时获取的资源 使用 RAII 机制的原因 RAII 是合理管理资源避免出现内存泄漏的常用方法 那

RAII机制介绍

RAII全程为Resource Acquisition Is Initialization(资源获取即初始化),RAII是C++语法体系中的一种常用的合理管理资源避免出现内存泄漏的常用方法。以对象管理资源,利用的就是C++构造的对象最终会被对象的析构函数销毁的原则。RAII的做法是使用一个对象,在其构造时获取对应的资源,在对象生命期内控制对资源的访问,使之始终保持有效,最后在对象析构的时候,释放构造时获取的资源。

使用RAII机制的原因

RAII是合理管理资源避免出现内存泄漏的常用方法。那么所谓的资源是如何进行定义的呢?在计算机系统中,资源是数量有限且对系统正常运行具有一定作用的元素。比如:网络套接字、互斥锁、文件句柄和内存等等,它们属于系统资源。由于系统的资源是有限的,就好比自然界的石油,铁矿一样,不是取之不尽,用之不竭的,所以,我们在编程使用系统资源时,都必须遵循一个步骤:

申请资源→使用资源→释放资源

#include  
      using namespace std; int main() { 
    int *arr = new int [10]; // Here, you can use the array  delete [] arr; arr = nullptr ; return 0; 

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

使用RAII机制的优点

  1. 不需要显式地释放资源。
  2. 采用这种方式,对象所需的资源只在其生命期内始终保持有效。

RAII机制的使用方法

#include  
     #include  
     #include  
     using namespace std; CRITICAL_SECTION cs; int gGlobal = 0; class MyLock { 
    public: MyLock() { 
    EnterCriticalSection(&cs); } ~MyLock() { 
    LeaveCriticalSection(&cs); } private: MyLock( const MyLock &); MyLock operator =(const MyLock &); }; void DoComplex(MyLock &lock ) { 
    } unsigned int __stdcall ThreadFun(PVOID pv) { 
    MyLock lock; int *para = (int *) pv; // I need the lock to do some complex thing DoComplex(lock); for (int i = 0; i < 10; ++i) { 
    ++gGlobal; cout<< "Thread " <<*para<<endl; cout<<gGlobal<<endl; } return 0; } int main() { 
    InitializeCriticalSection(&cs); int thread1, thread2; thread1 = 1; thread2 = 2; HANDLE handle[2]; handle[0] = ( HANDLE )_beginthreadex(NULL , 0, ThreadFun, ( void *)&thread1, 0, NULL ); handle[1] = ( HANDLE )_beginthreadex(NULL , 0, ThreadFun, ( void *)&thread2, 0, NULL ); WaitForMultipleObjects(2, handle, TRUE , INFINITE ); return 0; } 

这个例子可以说是实际项目的一个模型,当多个进程访问临界变量时,为了不出现错误的情况,需要对临界变量进行加锁;上面的例子就是使用的Windows的临界区域实现的加锁。但是,在使用CRITICAL_SECTION时,EnterCriticalSection和LeaveCriticalSection必须成对使用,很多时候,经常会忘了调用LeaveCriticalSection,此时就会发生死锁的现象。当我将对CRITICAL_SECTION的访问封装到MyLock类中时,之后,我只需要定义一个MyLock变量,而不必手动的去显示调用LeaveCriticalSection函数。

RAII总结

RAII机制保证了异常安全,并且也为程序员在编写动态分配内存的程序时提供了安全保证。但它也存在一些缺点,缺点就是有些操作可能会抛出异常,如果放在析构函数中进行则不能将错误传递出去,那么此时析构函数就必须自己处理异常。这在某些时候是很繁琐的。

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

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

(0)
上一篇 2026年3月17日 上午10:17
下一篇 2026年3月17日 上午10:18


相关推荐

  • idea整理代码idea快捷键

    idea整理代码idea快捷键idea整理代码快捷键:Catl+Alt+L

    2022年10月12日
    7
  • laravel微信自定义分享

    laravel微信自定义分享

    2021年10月28日
    66
  • 使用xsync脚本分发「建议收藏」

    使用xsync脚本分发「建议收藏」为什么使用xsync脚本来分发文件因为操作简单,只需要执行脚本在后面加上需要分发的文件就行了然后底层不一致,scp使用的是安全拷贝,而xsync使用的是增量拷贝由于底层不一致,xsync比scp快上许多使用脚本来分发文件之前不同节点之间的免密登录安排上脚本实现#!/bin/bash#1输入参数个数,如果没有参数就会退出pcount=$#if((pcount==0));thenechonoargs;exit;fi#2需要分发的文件名称p1=$1fname=`

    2022年5月18日
    56
  • Json字符串和js对象之间的转换

    Json字符串和js对象之间的转换Json 字符串和 js 对象之间的转换 JSON stringify 将 js 对象转为 json 字符串 JSON parse 将 JSON 字符串转为 js 对象

    2026年1月26日
    3
  • 复制粘贴不到远程桌面_设置服务器复制粘贴

    复制粘贴不到远程桌面_设置服务器复制粘贴在远程服务器上打开任务管理器,在进程里面找到rdpclip进程(或者剪贴板监视器),点击“结束进程”打卡DOS命令符,输入rdpclip后,确认,从新打开远程剪贴服务。

    2022年8月19日
    11
  • PyCharm入门教程——保存和还原更改

    PyCharm入门教程——保存和还原更改PyCharm 最新版本下载 JetBrainsPyC 是一种 PythonIDE 其带有一整套可以帮助用户在使用 Python 语言开发时提高其效率的工具 此外 该 IDE 提供了一些高级功能 以用于 Django 框架下的专业 Web 开发 PyCharm 会自动保存您在文件中所做的更改 保存由各种事件触发 例如编译 运行 调试 执行版本控制操作 关闭文件或项目或完全退出 IDE 实际事件是预定义的

    2026年3月27日
    3

发表回复

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

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