因为C++支持一种更棒的方法:"resource acquisition is initialization"技术。基本思想是使用局部对象代理资源,局部变量在析构时将会自动释放资源。用这种方式,这样程序开发人员将不会遗忘资源的释放
// wrap a raw C file handle and put the resource acquisition and release
// in the C++ type's constructor and destructor, respectively
class File_handle {
FILE* p;
public:
File_handle(const char* n, const char* a)
{ p = fopen(n,a); if (p==0) throw Open_error(errno); }
File_handle(FILE* pp)
{ p = pp; if (p==0) throw Open_error(errno); }
~File_handle() { fclose(p); }
operator FILE*() { return p; } // if desired
// ...
};
// use File_handle: uses vastly outnumber the above code
void f(const char* fn)
{
File_handle f(fn,"rw"); // open fn for reading and writing
// use file through f
} // automatically destroy f here, calls fclose automatically with no extra effort
// (even if there's an exception, so this is exception-safe by construction)
在一个系统中,最糟糕的方式是我们需要为每一个资源设计一个"resource handle"类。然而,我们不是必须用一个"finally"来处理资源。在一个现实的系统中,资源的处理代码远远超过了各种资源的数量,因此,使用“resource acquisition is initialization”技术来处理比使用"finally"结构更加简练。
Because C++ supports an alternative that is almost always better: The “resource acquisition is initialization” technique. The basic idea is to represent a resource by a local object, so that the local object’s destructor will release the resource. That way, the programmer cannot forget to release the resource. For example:
// wrap a raw C file handle and put the resource acquisition and release
// in the C++ type's constructor and destructor, respectively
class File_handle {
FILE* p;
public:
File_handle(const char* n, const char* a)
{ p = fopen(n,a); if (p==0) throw Open_error(errno); }
File_handle(FILE* pp)
{ p = pp; if (p==0) throw Open_error(errno); }
~File_handle() { fclose(p); }
operator FILE*() { return p; } // if desired
// ...
};
// use File_handle: uses vastly outnumber the above code
void f(const char* fn)
{
File_handle f(fn,"rw"); // open fn for reading and writing
// use file through f
} // automatically destroy f here, calls fclose automatically with no extra effort
// (even if there's an exception, so this is exception-safe by construction)
In a system, in the worst case we need a “resource handle” class for each resource. However, we don’t have to have a “finally” clause for each acquisition of a resource. In realistic systems, there are far more resource acquisitions than kinds of resources, so the “resource acquisition is initialization” technique leads to less code than use of a “finally” construct.
Also, have a look at the examples of resource management in Appendix E of TC++PL3e.
https://isocpp.org/wiki/faq/exceptions#finally