Resource Acquisition Is Initialization(RAII Idiom)
原文链接:http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Resource_Acquisition_Is_Initialization
Intent
- To guarantee release of resource(s) at the end of a scope
- To provide basic exception safety guarantee
Also Known As
- Execute-Around Object
- Resource Release Is Finalization
- Scope-Bound Resource Management
Motivation
scope or object. Quite often it means a pair of function calls - one to acquire a resource and another one to release it. For example, new/delete, malloc/free, acquire/release, file-open/file-close, nested_count++/nested_count--, etc. It is quite easy to forget
to write the "release" part of the resource management "contract". Sometimes the resource release function is never invoked: this can happen when the control flow leaves the scope because of return or an exception. It is too dangerous to trust the programmer
that he or she will invoke resource release operation in all possible cases in the present and in the future. Some examples are given below.
void foo ()
{
char * ch = new char [100];
if (...)
if (...)
return;
else if (...)
if (...)
else
throw "ERROR"; delete [] ch; // This may not be invoked... memory leak!
}
void bar ()
{
lock.acquire();
if (...)
if (...)
return;
else
throw "ERROR"; lock.release(); // This may not be invoked... deadlock!
}
that relieves the burden of calling "resource release" operation in a clever way.
Solution and Sample Code
always be invoked (of a successfully constructed object) when control flow leaves the scope because of a return statement or an exception.
// Private copy constructor and copy assignment ensure classes derived
// from class NonCopyable cannot be copied.
class NonCopyable
{
NonCopyable (NonCopyable const &); // private copy constructor
NonCopyable & operator = (NonCopyable const &); // private assignment operator
};
template <class T>
class AutoDelete : NonCopyable
{
public:
AutoDelete (T * p = 0) : ptr_(p) {}
~AutoDelete () throw() { delete ptr_; }
private:
T *ptr_;
}; class ScopedLock : NonCopyable// Scoped Lock idiom
{
public:
ScopedLock (Lock & l) : lock_(l) { lock_.acquire(); }
~ScopedLock () throw () { lock_.release(); }
private:
Lock& lock_;
}; void foo ()
{
X * p = new X;
AutoDelete<X> safe_del(p); // Memory will not leak
p = 0;
// Although, above assignment "p = 0" is not necessary
// as we would not have a dangling pointer in this example.
// It is a good programming practice. if (...)
if (...)
return; // No need to call delete here.
// Destructor of safe_del will delete memory
}
void X::bar()
{
ScopedLock safe_lock(l); // Lock will be released certainly
if (...)
if (...)
throw "ERROR";
// No need to call release here.
// Destructor of safe_lock will release the lock
}
Acquiring resource(s) in constructor is not mandatory in RAII idiom but releasing resources in the destructor is the key. Therefore, it is also known (rarely though) as Resource Release is Finalization idiom.
It is important in this idiom that the destructor should not throw exceptions. Therefore, the destructors have no-throw specification but it is optional. std::auto_ptr and boost::scoped_ptr are ways of quickly using RAII idiom for memory resources. RAII is
also used to ensure exception safety. RAII makes it possible to avoid resource leaks without extensive use of try/catch blocks and is widely used in the software industry.
Many classes that manage resources using RAII, do not have legitimate copy semantics (e.g., network connections, database cursors, mutex). The NonCopyable class shown before prevents copying of objects that
implement RAII. It simply prevents access to the copy-constructor and the copy-assignment operator by making them private. boost::scoped_ptr is an example of one such class that prevents copying while holding memory resources. The NonCopyable class
states this intention explicitly and prevents compilation if used incorrectly. Such classes should not be used in STL containers. However, every resource management class that implements RAII does not have to be non-copyable like the above two examples. If
copy semantics are desired, boost::shared_ptr can be used to manage memory resources. In general, non-intrusivereference counting is used to provide copy semantics as well as RAII.
Consequences
RAII is not without its limitations. The resources which are not memory and must be released deterministically and may
throw exceptions usually aren't handled very well by C++ destructors. That's because a C++ destructor can't propagate errors to the enclosing scope (which is potentially winding up). It has no return value and it should not propagate exceptions outside itself.
If exceptions are possible, then the destructor must handle the exceptional case within itself somehow. Nevertheless, RAII remains the most widely used resource management idiom in C++.
Known Uses
- Virtually all non-trivial C++ software
- std::auto_ptr
- boost::scoped_ptr
- boost::mutex::scoped_lock
Related Idioms
Reference Counting
Non copyable
Locking idiom is a special case of RAII applied to operating system synchronization primitives such as mutex and semaphores
Reference
- Resource
Acquisition Is Initialization on Wikipedia - Exception Safety: Concepts and Techniques,
Bjarne Stroustrup - The RAII Programming Idiom
- Sutter, Herb (1999). Exceptional C++. Addison-Wesley. ISBN
0-201-61562-2. - C++
Patterns: Execute Around Sequences, Kevlin Henney
Resource Acquisition Is Initialization(RAII Idiom)的更多相关文章
- Constructor Acquires, Destructor Releases Resource Acquisition Is Initialization
w https://zh.wikipedia.org/wiki/RAII RAII要求,资源的有效期与持有资源的对象的生命期严格绑定,即由对象的构造函数完成资源的分配(获取),同时由析构函数完成资源的 ...
- RAII(Resource Acquisition Is Initialization)简介
RAII(Resource Acquisition Is Initialization),也称为“资源获取就是初始化”,是C++语言的一种管理资源.避免泄漏的惯用法.C++标准保证任何情况下,已构造的 ...
- RAII(Resource Acquisition Is Initialization)资源获得式初始化
当在编写代码中用到异常,非常重要的一点是:“如果异常发生,程序占用的资源都被正确地清理了吗?” 大多数情况下不用担心,但是在构造函数里有一个特殊的问题:如果一个对象的构造函数在执行过程中抛出异常,那么 ...
- Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [spring-mybatis.xml]: Initialization of bean failed
- <Effective C++>读书摘要--Resource Management<一>
1.除了内存资源以外,Other common resources include file descriptors, mutex locks, fonts and brushes in graphi ...
- C++学习指南
转载于stackoverflow:http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list 感谢Ge ...
- The Definitive C++ Book Guide and List
学习c++的书单 转自 http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list Beginner ...
- More C++ Idioms
Table of Contents Note: synonyms for each idiom are listed in parentheses. Adapter Template TODO Add ...
- The Definitive C++ Book Guide and List--reference
http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list Reference Style - All ...
随机推荐
- C#的前世今生,学会C#还能找到高薪工作吗?
其实C#,.net正在逐步淡出程序员的视野是正在发生的现实,量子及量子的小伙伴们,还在坚持写C#代码的人几乎没有了,回忆起过去那些写C#时候的美好时光,真是不胜唏嘘,最近园子里的一篇<C#程序员 ...
- VMware虚拟网络编辑器
摘要:很多已经使用VMware很久的同学,也没有接触过VMware的虚拟网络编辑器这个工具.其 实这个工具非常有用.功能也很强大. 我们都知道,安装了VMware软件后,系统中会自动出现VMnet ...
- Spring.Net 简单入门学习
Spring.NET IoC容器的用法. 通过简单的例子学习Spring.Net 1.先创建一个控制台程序项目. 2.添加IUserInfoDal 接口. namespace Spring.Net { ...
- 【javascript】箭头函数
ES6标准新增了一种新的函数:Arraw Function(箭头函数). x => x * x 这个函数相当于 function (x){ return x * x; } 题外话:user st ...
- 20.Python笔记之SqlAlchemy使用
Date:2016-03-27 Title:20.Python笔记之SqlAlchemy使用 Tags:python Category:Python 作者:刘耀 博客:www.liuyao.me 一. ...
- NSUserDefaults:熟悉与陌生(转)
转载自:http://swiftcafe.io/2016/04/04/nsuserdefaults/?hmsr=toutiao.io&utm_medium=toutiao.io&utm ...
- Nginx高级使用
1.用户认证 客户端访问限制deny 客户端地址: 拒绝访问allow 客户端地址: 允许访问 rpm -q httpd-tools yum -y install httpd-tools user h ...
- 【poj1737】 Connected Graph
http://poj.org/problem?id=1737 (题目链接) 题意 求n个节点的无向连通图的方案数,不取模w(゚Д゚)w Solution 刚开始想了个第二类斯特林数,然而并不知道怎么求 ...
- js之 matches (可以取代jq的 delegate 方法)
问题:请给#wrap 下面的子元素添加点击事件! <div id="wrap"> <a class="btn" href="http ...
- Table
Table tb = new Table();TableRow r = new TableRow(); TableCell c = new TableCell();c.Text = "Sta ...