WEB开发网
开发学院软件开发C语言 RAII 阅读

RAII

 2009-06-08 08:32:23 来源:WEB开发网   
核心提示: 不错,这看起来很完美,RAII(2),我们解决了异常情况下内存资源释放的问题,但是,资源(这里的资源通常是指的是非内存资源)获取即使初始化,换而言之,对于非内存资源呢?例如:void f(){ FILE* pf1 = fopen("killercat.blog1",

不错,这看起来很完美,我们解决了异常情况下内存资源释放的问题。但是,对于非内存资源呢?例如:

void f()
{   
    FILE* pf1 = fopen("killercat.blog1", "w");
    FILE* pf2 = fopen("killercat.blog2", "w");
    FILE* pf3 = fopen("killercat.blog3", "w");
    // ...   
    try
    {       
        f2(); // f2 可能抛出异常   
    } catch (const xxx&) {       
        fclose(pf1); // 又回到了丑陋的代码
        fclose(pf2);
        fclose(pf3);   
    }
}

很显然,FILE 不是一个类,我们无法使用诸如 autoptr 这样的管理器来进行资源的生命周期管理,对非内存资源的生命周期的管理,我们有另外一种方式可循:把非内存资源的生命周期的管理转化为内存资源的生命周期的管理。

RAII(Resource Acquisition Is Initialization),资源(这里的资源通常是指的是非内存资源)获取即使初始化,换而言之,我们将利用 C++ 构造函数和析构函数来维护一个不变式(invariant):对象存在则资源(常常指非内存资源也可以只内存资源)有效。一个经典的例子就是:

// use an object to represent a resource ("resource acquisition is initialization")
class File_handle
{
    // belongs in some support library
    FILE* p;
public:
    File_handle(const char* pp, const char* r)
    {
        p = fopen(pp,r);
        if (p==0)
            throw Cannot_open(pp);
    }
    File_handle(const string& s, const char* r)
    {
        p = fopen(s.c_str(),r);
        if (p==0)
            throw Cannot_open(pp);
    }
    ~File_handle()
    {
        fclose(p);
    } // destructor
    // copy operations and access functions
};
 
void f(string s)
{
    File_handle file(s, "r");
    // use file
}

上一页  1 2 3 4 5  下一页

Tags:RAII

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接