RAII基本含义
Resource Acquisition Is Initialization(RAII)是一种设计思想,为了实现:
- 保证资源在作用域结束后被释放
- 提供基本的异常安全
RAII这个名字不够直观,实际上另一个名字更能体现这种思想,Scope-Bound Resource Management(SBRM),即作用域界定资源管理。
设计动机
资源管理难题
资源在离开函数作用域前,应当被释放,除非它的管理权被转移到另一个作用域。因此,资源获取和资源释放的函数经常成对出现。然而,尽管我们写了资源释放函数,但他们可能由于return或者exception导致的程序控制流离开作用域而不会被调用。例如下面的例子:
1 | void foo () |
这是一个普遍存在的控制流抽离问题。RAII思想可以帮助我们更方便的实现资源的管理。
解决方案
可以利用C++语言对于析构对象的特性,将资源释放的操作放入到一个对象实例中。C++保证析构函数总会在控制流离开作用域时被调用,不论是否发生return或者exception。代码示例如下:
1 | // Private copy constructor and copy assignment ensure classes derived from class NonCopyable cannot be copied. |
python的with方法,类似于这种设计思想。
Lock_guard对mutex的管理
c++11中lock_guard对mutex互斥锁的管理就是典型的RAII机制。代码如下:
1 | /// @brief Scoped lock idiom. |
为了保证lock_guard对象不被错误使用而产生不可预知的后果,因此lock_guard对象删除了拷贝构造和赋值运算符,保证lock_guard不被复制。
参考文献
https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Resource_Acquisition_Is_Initialization