baidu百科

RAII

百科名片

RAII,也称为“资源获取就是初始化”,是c++等编程语言常用的管理资源、避免内存泄露的方法。它保证在任何情况下,使用对象时先构造对象,最后析构对象。

编辑本段RAII简介

RAII[1](Resource Acquisition Is Initialization),也成为“资源获取就是初始化”,是C++语言的一种管理资源、避免泄漏的惯用法。C++标准保证任何情况下,已构造的对象最终会销毁,即它的析构函数最终会被调用。简单的说,RAII 的做法是使用一个对象,在其构造时获取资源,在对象生命期控制对资源的访问使之始终保持有效,最后在对象析构的时候释放资源。

编辑本段RAII的分类

根据RAII[2]对资源的所有权可分为常性类型和变性类型,代表者分别是boost:shared_ptr<>[2]和std::auto_ptr<>;从所管资源的初始化位置上可分为外部初始化类型和内部初始化类型。
常性类型是指获取资源的地点是构造函数,释放点是析构函数,并且在这两点之间的一段时间里,任何对该RAII类型实例的操纵都不应该从它手里夺走资源的所有权。变性类型是指可以中途被设置为接管另一个资源,或者干脆被置为不拥有任何资源。外部初始化类型是指资源在外部被创建,并被传给RAII实例的构造函数,后者进而接管了其所有权。boost:shared_ptr<>和std::auto_ptr<>都是此类型。与之相对的是内部初始化类型。
其中,常性且内部初始化的类型是最为纯粹的RAII形式,最容易理解,最容易编码。

编辑本段RAII实际应用

每当处理需要配对的获取/释放函数调用的资源时,都应该将资源封装在一个对象中,实现自动资源释放。例如,我们无需直接调用一对非成员函数OpenPort/ClosePort,而是可以考虑定义常性且内部初始化的RAII概念的“端口”操作类:
class Port{
public:
Port(const string& destination);//调用OpenPort
~Port();//调用ClosePort
};
void DoSomething(){
Port port1(“server1:80”);
}
shared_ptr<Port> post2 = /*…*/; //port2在最后一个引用它的
//shared_ptr离开作用域后关闭
通过使用上述RAII类型,可以避免程序员忘记关闭端口而引起的泄漏,还可以确保异常发生时栈展开过程中自动释放端口资源。

编辑本段RAII与STL容器

STL容器是基于值语义的,在容器内部,对象是常被复制的。如果RAII类型需要存入STL容器,需要作一些处理。
class Resource
{
public:
Resource() {/*分配资源*/}
~ Resource() {/*释放资源*/}
private:
int handle;
};
std::map< Identifier, Resource > resourceMap;
以上代码中STL容器对Resource的复制将导致运行期错误。最好的方法是让RAII类型继承于boost::noncopyable[2],而后在容器中使用引用计数的指针:
class Resource : public boost::noncopyable
{
public:
Resource() {/*分配资源*/}
~ Resource() {/*释放资源*/}
private:
int handle;
};
typedef boost::shared_ptr<Resource> PointerToResourceType;
typedef std::map< Identifier, PointerToResourceType> ResourceMapType;
ResourceMapType resourceMap;
作为替代,还可以使用非拷贝行为的容器:boost::ptr_map<Identifier,Resource> map;

[EffectiveC++]item13:Use objects to manage resources(RAII)的更多相关文章

  1. Django(九)模型:dj查询数据库的函数(方法)

    一.查询函数 通过模型类.objects属性可以调用如下函数,实现对模型类对应的数据表的查询. 函数表 函数名 功能 返回值 说明 get 返回表中满足条件的一条且只能有一条数据. 返回值是一个模型类 ...

  2. 单元测试系列之九:Sonar 常用代码规则整理(一)

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 摘要:公司部署了一套sonar,经过一段时间运行,发现有一些问题出现频率很高,因此有必要将这些问题进行整理总结和分 ...

  3. Re:从零开始的Spring Security Oauth2(三)

    上一篇文章中我们介绍了获取token的流程,这一篇重点分析一下,携带token访问受限资源时,内部的工作流程. @EnableResourceServer与@EnableAuthorizationSe ...

  4. Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

    参考: https://my.oschina.net/gaussik/blog/513444 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 ...

  5. 深入理解JS:执行上下文中的this(一)

    目录 执行上下文与执行上下文栈 this 全局环境 函数环境 总结 参考 1.执行上下文与执行上下文栈 (1)什么是执行上下文? 在 JavaScript 代码运行时,解释执行全局代码.调用函数或使用 ...

  6. MyBatis6:MyBatis集成Spring事物管理(下篇)

    前言 前一篇文章<MyBatis5:MyBatis集成Spring事物管理(上篇)>复习了MyBatis的基本使用以及使用Spring管理MyBatis的事物的做法,本文的目的是在这个的基 ...

  7. Spring7:基于注解的Spring MVC(下篇)

    Model 上一篇文章<Spring6:基于注解的Spring MVC(上篇)>,讲了Spring MVC环境搭建.@RequestMapping以及参数绑定,这是Spring MVC中最 ...

  8. 原创 C++应用程序在Windows下的编译、链接:第三部分 静态链接(二)

    3.5.2动态链接库的创建 3.5.2.1动态链接库的创建流程 动态链接库的创建流程如下图所示: 在系统设计阶段,主要的设计内容包括:类结构的设计以及功能类之间的关系,动态链接库的接口.在动态链接库中 ...

  9. 解决方案:带格式化文本控件( RichText)的模板如果在InfoPath的浏览器中加载可能出现 COM 组件的80040154错误

      建议大家在微软的组件出现问题时,在GOOGLE上搜索解决方案,一般来说,总有结果:  带格式化文本控件( RichText)的模板如果在InfoPath的浏览器中加载,可能出现 COM 组件的80 ...

随机推荐

  1. docker中的命令参数(小白常用)

    1 docker run run是最常用的命令,他是docker creat和docker start命令的组合,创建容器并启动它.run的参数比较难理解的是-i 和-t 以及-d,分别说说这三个. ...

  2. Veloce2 Emulator

    High capacity, high-speed, multi-application powerhouse for simulation and emulation of SoC designs ...

  3. Apache mod_rewrite

    mod_rewrite是Apache的一个非常强大的功能,它可以实现伪静态页面.下面我详细说说它的使用方法!对初学者很有用的哦! 1.检测Apache是否支持mod_rewrite phpinfo() ...

  4. <深入理解JavaScript>学习笔记(1)_编写高质量JavaScript代码的基本要点

    注:本文是拜读了 深入理解JavaScript 之后深有感悟,故做次笔记方便之后查看. JQuery是一个很强大的JavaScript 类库,在我刚刚接触JavaScript的就开始用了. JQuer ...

  5. c# 旋转图片 无GDI+一般性错误

    using (System.Drawing.Bitmap backgroudImg = System.Drawing.Bitmap.FromFile(DoubleClickPicInfo.FileNa ...

  6. Bundle传递数据,Handler更新UI

    Bundle主要用于传递数据:它保存的数据,是以key-value(键值对)的形式存在的. Bundle经常使用在Activity之间或者线程间传递数据,传递的数据可以是boolean.byte.in ...

  7. 如何迎接新的 .NET 时代

    看完.NET 基金会. Roslyn 编译器 ,应该已经能慢慢了解,现在所谓的“.NET 开源”.“.NET Open Source”并不是完全把现有的 .NET Framework 整个打开(虽然这 ...

  8. java设计模式-观察者模式,装饰者模式

    1.1定义 慨念:定义了对象之间的一对多的依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新. 即:主题和观察者定义了一对多的关系,观察者依赖于主题,只要主题发生变化,观察者就 ...

  9. js中contains()方法的了解

    今天第一次碰到了contains()方法,处于好奇了解了一下:发现在某些场合还是挺有用的. contains(),js原生方法,用于判断DOM元素的包含关系: 需要注意的是:它以HTMLElement ...

  10. VScode基础设置

    安装依赖包: • One Monokai • Aglia • One Dark Pro • Material Icon   漂亮的主题: Themes Quokka 是一个调试工具插件,能够根据你正在 ...