分类: C/C++
2013-01-30 09:33:51
C++程序的设计机制3 RAII机制(1)
为了管理内存等资源,C++程序员通常采用RAII机制(资源获取即初始化),在使用资源的类的构造函数中申请资源,然后使用,最后在析构函数中释放资源。今天本文为你介绍RAII机制,一起来看。
AD:
RAII(Resource Acquisition Is Initialization )机制是BjarneStroustrup首先提出的。要解决的是这样一个问题:
在C++中,如果在这个程序段结束时需要完成一些资源释放工作,那么正常情况下自然是没有什么问题,但是当一个异常抛出时,释放资源的语句就不会被 执行。于是BjarneStroustrup就想到确保能运行资源释放代码的地方就是在这个程序段(栈帧)中放置的对象的析构函数了,因为stack winding会保证它们的析构函数都会被执行。将初始化和资源释放都移动到一个包装类中的好处:
1、应用场景
1)文件操作
我们可以是用这个机制将文件操作包装起来完成一个异常安全的文件类。实现上,注意将复制构造函数和赋值符私有化,这个是通过一个私有继承类完成的,因为这两个操作在此并没有意义,当然这并不是RAII所要求的。
1. /*
2. * =====================================================================================
3. *
4. * Filename: file.cpp
5. *
6. * Description: RAII for files
7. *
8. * Version: 1.0
9. * Created: 05/09/2011 06:57:43 PM
10.* Revision: none
11.* Compiler: g++
12.*
13.* Author: gnuhpc (http://blog.csdn.net/gnuhpc), warmbupt@gmail.com
14.*
15.* =====================================================================================
16.*/
17.#include
18.#include
19.#include
20.
21.using namespace std;
22.class NonCopyable
23.{
24.public:
25.NonCopyable(){};
26.private:
27.NonCopyable (NonCopyable const &); // private copy constructor
28.NonCopyable & operator = (NonCopyable const &); // private assignment operator
29.};
30.
31.class SafeFile:NonCopyable{
32.public:
33.SafeFile(const char* filename):fileHandler(fopen(filename,"w+"))
34.{
35.if( fileHandler == NULL )
36.{
37.throw runtime_error("Open Error!");
38.}
39.}
40.~SafeFile()
41.{
42.fclose(fileHandler);
43.}
44.
45.void write(const char* str)
46.{
47.if( fputs(str,fileHandler)==EOF )
48.{
49.throw runtime_error("Write Error!");
50.}
51.}
52.
53.void write(const char* buffer, size_t num)
54.{
55.if( num!=0 && fwrite(buffer,num,1,fileHandler)==0 )
56.{
57.throw runtime_error("Write Error!");
58.}
59.}
60.private:
61.FILE *fileHandler;
62.SafeFile(const SafeFile&);
63.SafeFile &operator =(const SafeFile&);
64.};
65.
66.int main(int argc, char *argv[])
67.{
68.SafeFile testVar("foo.test");
69.testVar.write("Hello RAII");
70.}
C++的结构决定了其原生支持RAII,而在Java 中,对象何时销毁是未知的,所以在Java 中可以使用try-finally做相关处理。参考资料