zoukankan      html  css  js  c++  java
  • RAII

    全称是Resource Acquisition is Initialization,翻译为资源获取就是初始化。

    其实就是利用栈上的局部对象在离开作用域时会自动释放的原理,在临时对象创建时初始化资源,或者将资源交给对象管理,当临时对象析构时释放资源,因为临时对象在离开其作用时会自动析构,也就会自动释放其对应资源。

    适用于对异常状况的处理,如果用try..catch或条件判断处理异常,除了在所有可能出现异常的位置要添加这些处理语句之外,还要手工的去释放相应的资源。有了RAII,只需要在一个作用域内将资源交给一个临时对象,就可以了,跳出该作用域时系统会自动资源。

    可以用于对内存,文件句柄,网络套接字,互斥锁等资源的管理

    对在堆上分配的资源,可用如下类管理

    class RAIIBase  

    {  

    protected:  

        RAIIBase(){}  

        ~RAIIBase(){}  

    private:      

        RAIIBase (const RAIIBase &);  

        RAIIBase & operator = (const RAIIBase &);  

        void * operator new(size_t size);   

        // 不定义任何成员  

    };  

    template<typename T>  

    class ResourceHandle: public RAIIBase //私有继承 禁用Base的所有继承操作  

    {  

    public:  

        explicit ResourceHandle(T * aResource):r_(aResource){}//获取资源  

        ~ResourceHandle() {delete r_; } //释放资源  

        T *get()    {return r_ ;} //访问资源  

    private:  

        T * r_;  

    };

    对于文件句柄的操作

    http://www.cnblogs.com/hsinwang/articles/214663.html

    class FileHandle {
    public:
        FileHandle(char const* n, char const* a) { p = fopen(n, a); }
        ~FileHandle() { fclose(p); }
    private:
        // 禁止拷贝操作
        FileHandle(FileHandle const&);
        FileHandle& operator= (FileHandle const&);
        FILE *p;
    };

    RAII惯用法同样适用于需要管理多个资源的复杂对象。例如,Widget类的构造函数要获取两个资源:文件myFile和互斥锁myLock。每个资源的获取都有可能失败并且抛出异常。为了正常使用Widget对象,这里我们必须维护一个不变式(invariant):当调用构造函数时,要么两个资源全都获得,对象创建成功;要么两个资源都没得到,对象创建失败。获取了文件而没有得到互斥锁的情况永远不能出现,也就是说,不允许建立Widget对象的半成品。如果将RAII惯用法应用于成员对象,那么我们就可以实现这个不变式:

    class Widget {
    public:
        Widget(char const* myFile, char const* myLock)
        : file_(myFile),     // 获取文件myFile
          lock_(myLock)      // 获取互斥锁myLock
        {}
        // ...
    private:
        FileHandle file_;
        LockHandle lock_;
    };

    FileHandleLockHandle类的对象作为Widget类的数据成员,分别表示需要获取的文件和互斥锁。资源的获取过程就是两个成员对象的初始化过程。在此系统会自动地为我们进行资源管理,程序员不必显式地添加任何异常处理代码。例如,当已经创建完file_,但尚未创建完lock_时,有一个异常被抛出,则系统会调用file_的析构函数,而不会调用lock_的析构函数。Bjarne所谓构造函数和析构函数与异常处理的交互作用,说的就是这种情形。

    综上所述,RAII的本质内容是用对象代表资源,把管理资源的任务转化为管理对象的任务,将资源的获取和释放与对象的构造和析构对应起来,从而确保在对象的生存期内资源始终有效,对象销毁时资源必被释放。换句话说,拥有对象就等于拥有资源,对象存在则资源必定存在。由此可见,RAII惯用法是进行资源管理的有力武器。C++程序员依靠RAII写出的代码不仅简洁优雅,而且做到了异常安全。难怪微软的MSDN杂志在最近的一篇文章中承认:若论资源管理,谁也比不过标准C++”

  • 相关阅读:
    2021,6,10 xjzx 模拟考试
    平衡树(二)——Treap
    AtCoder Beginner Contest 204 A-E简要题解
    POJ 2311 Cutting Game 题解
    Codeforces 990G GCD Counting 题解
    NOI2021 SDPTT D2T1 我已经完全理解了 DFS 序线段树 题解
    第三届山东省青少年创意编程与智能设计大赛总结
    Luogu P6042 「ACOI2020」学园祭 题解
    联合省选2021 游记
    Codeforces 1498E Two Houses 题解 —— 如何用结论吊打标算
  • 原文地址:https://www.cnblogs.com/suntp/p/6426285.html
Copyright © 2011-2022 走看看