C++惯用法之RAII

C++号称是多范式的通用编程语言,但是RAII实际上已在C++编程技术中变成 不可或缺的核心技术。RAII几乎无处不在的身影不仅仅来自于C++之父的大力提 倡,更来自于这一技术本身的简单,高效和几乎无所不能的适应面。

如 果您还没有听说过RAII的话,那么我在这里再重新叙述一遍,RAII是下列英文短 语的首字母缩写:

Resource Acquisition Is Initialisation

这 句话直译为中文的意思是: 资源获得即初始化。这只是一个短语,不能指望靠 望文生义来了解字面背后的完整含义,但是短语本身的确反映了重要的论点: 资源是其一,初始化是其二。

RAII 是有关资源的。资源是一切需要分配 的数量有限的资料。比如,存储器,文件句柄,网络套接字端口,数据库连接, 以及线程池等。基本上,由于物理的限制,所有的资料都是有限的。在某些特殊 的情况下,资料由于局部的极大丰富而丧失了资源的意义,比如沙子,空气等。 但是在大多数情况下,资料都是有限的,需要我们善加管理。

资源管理 的最基本形式就是善始善终。申请了资源,用完了,就要归还。在C++程序员生 活里最常见的就是内存资源,资源管理就是内存管理: 申请了内存,不管什么 时候逻辑上完成了对这片内存的使用,内存就要被正确地释放。注意这里的用词 是"不管什么时候". 在实际应用中,内存的使用逻辑是如此复杂,使 得逻辑上界定某块内存的生命周期会成为非常繁琐非常复杂的任务,而内存资源 就会在人类智力的疏漏中泄漏出去。而即使是简单情况,内存也会在菜鸟程序员 手忙脚乱的拙劣中溜走。所以资源管理虽然可以简化为一句"有始有终 ",在实际当中很难得到保证。

有 一类语言,比如Java,把内存资 源接管了,提供了所谓的自动内存管理,使用内存分配算法的方式为程序员模拟 了一个取之不尽用之不竭的准无穷内存模式。背后的思想是,在普通应用中,内 存的使用在空间和时间上都是相对集中的,这就允许用较少的内存来应付时间积 累上无限的内存请求。程序员使用这类语言就不用再考虑内存的释放问题。负担 就大大减轻了。

自动内存管理从原理上把内存资源倍增而产生一种资料 (准)无限的虚拟环境,从而把程序员从繁重的内存资源管理上解放出来,化更 多的精力考虑实际的事务代码,提高了生产率。但是它也有自己的局限。一,自 动内存管理算法比较复杂,本身的程序就要占一定内存,同时自动内存管理用时 间换空间,还要求实际物理内存至少为应用最大瞬时所需内存的两倍才能较好地 发挥作用,这一要求说明,自动内存管理其实已经不是在管理短缺意义上的 "资源",而是为不那么浪费地使用丰富的资料提供一种说得过去的代 用方案。其次,由于自动内存管理是与具体的应用分离的,无法知道最合适的切 入点,所以自动内存管理的介入基本是不可预测的。这限制了自动内存管理在那 些对时间响应要求比较严格的程序中的应用。最后,自动内存管理仅是对内存资 源的管理,它无法管理其它的资源。除了内存,程序员往往要和其它的资源打交 道。自动内存管理模式无法应用到其它类型的资源管理。

C++提供了RAII 作为一个真正意义上的资源管理实用方案。这也是C++语言在资源管理这一意义 更加广泛的问题上作出的贡献。虽然其实用意义如此重大,但是其做法却很简单 ,就是用类来表示资源,在类的构造函数里分配资源,在类的析构函数里释放资 源。比如,

class Resource {

public:

Resource(const char *name) : _resource(alloc_resource(name)) {……}

~Resource() { release_resource (_resource); }

};

资源类的使用也很简单,按 泛围使用。比如,有一个事务处理,使用到了某种资源。如果这一事务可以用一 个函数来表示,那么,可以简单地用一个在函数入口处分配的资源变量来表示资 源分配。例如:

void transaction1(const char *res_name)

{

Resource res(res_name);

// 后面 是使用资源res

}

时间: 2024-11-02 13:28:17

C++惯用法之RAII的相关文章

XQuery高级应用:开发应用程序惯用法

本文配套源码 开始之前 讨论XQuery示例代码之前,先介绍一下如何学好本教程,如何安装和使用所附的源代码(参见下载 小节). 关于本教程 本教程介绍如何使用XQuery开发应用程序和中间件.列举了在应用程序开发中XQuery的一些局限,就如何克服这些局限提供了切实可行的建议,同时强调XQuery在处理这些问题时的优势和缺点在哪里.然后在此基础上,利用大量的篇幅介绍了应用程序开发中一系列常见的编程惯用法: 使用扩展函数 单元测试与断言 递归与排序 高阶函数 目标 本教程的目的是帮助您学习如何使用

php设计模式介绍之编程惯用法第1/3页_php技巧

在这里总结的许多编程惯用法都是很值得做为单独一个章节的,甚至一本书的.你应该把这章做为PHP模式设计使用惯用法的相关介绍,而且查看一些列出的参考书来进行更深入的学习. 测试你的代码 可能没有什么代码惯用法比测试代码更加重要了.好的测试可以提高开发速度. 可能一开始,这句格言会和你的直觉相矛盾.你可能会断言,测试是自由的障碍物.事实上恰恰相反,如果你十分完整的运行那些测试来检查你的软件的公共接口,你就可能在不改变(或者更加糟糕,破坏)原来的应用软件的前提下改变自己系统内在的执行.测试并检验你的公共

C++内存管理学习笔记(4)

/****************************************************************/ /*            学习是合作和分享式的! /* Author:Atlas                    Email:wdzxl198@163.com    /*  转载请注明本文出处: *   http://blog.csdn.net/wdzxl198/article/details/9094793 /**********************

C++中的RAII机制详解_C 语言

前言 在写C++设计模式--单例模式的时候,在写到实例销毁时,设计的GC类是很巧妙的,而这一巧妙的设计就是根据当对象的生命周期结束时会自动调用其析构函数的,而这一巧妙的设计也是有专业的名词的--RAII.那以下将围绕RAII,全面的讲解RAII的相关知识. 什么是RAII? RAII是Resource Acquisition Is Initialization的简称,是C++语言的一种管理资源.避免泄漏的惯用法.利用的就是C++构造的对象最终会被销毁的原则.RAII的做法是使用一个对象,在其构造

C++的RAII在WebKit中的应用

先看下面这段WebKit中的代码: { NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel); //Do something else... } 看看NestingLevelIncrementer的实现,就知道与另一种写法看似是等价的: { ++m_scriptNestingLevel; //Do something else... --m_scriptNestingLevel; } 上面的实现是不是用加一个类

extern "C"的用法解析

1.引言 C++语言的创建初衷是"a better C",但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同.作为一种欲与C兼容的语言, C++保留了一部分过程式语言的特点(被世人称为"不彻底地面向对象"),因而它可以定义不属于任何类的全局变量和函数.但是,C++毕竟是一种面向对象的程序设计语言 ,为了支持函数的重载,C++对全局函数的处理方式与C有明显的不同.   2.从标准头文件说起 某企业曾经给出如下的一道面试题: 面试题

细说 ASP.NET Cache 及其高级用法

原文:细说 ASP.NET Cache 及其高级用法 许多做过程序性能优化的人,或者关注过程程序性能的人,应该都使用过各类缓存技术. 而我今天所说的Cache是专指ASP.NET的Cache,我们可以使用HttpRuntime.Cache访问到的那个Cache,而不是其它的缓存技术. 以前我在[我心目中的Asp.net核心对象] 这篇博客中简单地提过它,今天我打算为它写篇专题博客,专门来谈谈它,因为它实在是太重要了.在这篇博客中, 我不仅要介绍它的一些常见用法,还将介绍它的一些高级用法. 在上篇

C语言宏高级用法 [总结]

1.前言  今天看代码时候,遇到一些宏,之前没有见过,感觉挺新鲜.如是上网google一下,顺便总结一下,方便以后学习和运用.C语言程序中广泛的使用宏定义,采用关键字define进行定义,宏只是一种简单的字符串替换,根据是否带参数分为无参和带参.宏的简单应用很容易掌握,今天主要总结一下宏的特殊符号及惯用法. (1)宏中包含特殊符号:#.##.       (2)宏定义用do{ }while(0) 2.特殊符号#.## (1)# When you put a # before an argumen

JSP监听器用法分析_JSP编程

本文实例讲述了JSP监听器用法.分享给大家供大家参考,具体如下: 监听器也叫Listener,是servlet服务的监听器.它可以监听客户端的请求,服务端的操作等.比如统计在线用户数量.每当增加一个HttpSession时,就会触发sessionCreate(HttpSessionEvent se)方法,这样就可以给在线人数加1.常用的监听器接口如下: 1. ServletContextAttributeListener监听对ServletContext属性的操作.比如增加,删除,修改属性. 2