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++”

  • 相关阅读:
    磁盘分区对齐的重要性
    linux命令详解:jobs命令
    linux命令详解:df命令
    linux命令详解:cat命令
    <mvc:annotation-driven />注解意义
    maven install 时提示“程序包 javax.crypto不存在”
    Java 字典排序
    Linux查看用户登陆历史记录
    警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property ..
    Eclipse启动tomcat 报“ A child container failed during start”
  • 原文地址:https://www.cnblogs.com/suntp/p/6426285.html
Copyright © 2011-2022 走看看