摘自《Extended STL》中译
RAII:资源获取即初始化
资源获取即初始化(RAII, Resource Acquisition Is Initialization)是指,当你获得一个资源的时候,不管这个资源是对象、内存、文件句柄或者其它什么,你都会在一个对象的构造函数中获得它,并且在该对象的析构函数中释放它。实现这种功能的类,我们就说它采用了"资源获取即初始化(RAII)"的方式。这样的类常常被称为封装类。
可以依据资源可变性和资源来源这两个特征,来对RAII进行分类。
资源可变性
如果一个封装类对其实例提供额外的功能,使得其实例能被赋予新资源,这个类表现出的这种特征即称为"可变的RAII",否则就是"不可变的RAII"。
不可变的RAII,是使用起来最简单的一种。说它简单,是因为在这种情况下,无需在封装类中提供用于指定资源的方法--不管是新分配的资源,还是对其他资源进行拷贝。这种RAII还意味着,类的析构函数总是可以假定,被封装的资源是有效的。
与此相反,提供可变的RAII的类,就需要实现下列功能中的绝大部分,或者全部:缺省的或者空的构造函数,拷贝构造函数,拷贝赋值操作,用于指定资源的方法。最重要的是,这样的类在析构函数和任何类似close()的方法中,释放资源前,都必须检测被封装的资源是不是null。
资源来源
对于提供RAII的类来说,第二个重要的特征是,它们通过什么途径获取自己所管理的资源。以std::string为代表的类,使用的是内部初始化的RAII:它管理的资源--即内存中用于保存字符的缓冲区--是由它自己创建的,这一资源对外永远是不可见的。与此不同的是,以std::auto_ptr为代表的类表现出外部初始化的RAII行为:它所管理的资源,是使用它的客户程序(通过另外的某种方式获得之后)交给它的。
内部初始化的RAII的封装类,一般比较容易实现,但是功能上也比较受限制,因为它们获取资源的机制是预先定义好的,并且是固定不变的。不过,这样的类用起来也容易一些,或者说,比较难被误用:因为客户代码几乎没有机会犯下能导致资源泄露的错误。