• C++进阶--RAII 资源获取即初始化


    //############################################################################
    /* 资源获取即是初始化 (RAII)
     * 
     * 使用对象来管理资源: (利用栈回退时一定会释放栈上对象的机制)
     * 	内存,硬件设备,网络句柄等
     */
    
    Mutex_t   mu = MUTEX_INITIALIZER;
     
    void functionA()
    {
       Mutex_lock( &mu );
       ... // 做一系列事情
       Mutex_unlock( &mu );      // 是否一定会被执行
    }
    
    
    /*
     * 解决方法:
     */ 
    class Lock {
       privat:
          Mutext_t* m_pm;
       public:
          explicit Lock(Mutex_t *pm) { Mutex_lock(pm); m_pm = pm;};
          ~Lock() { Mutex_unlock(m_pm); };
    }
    
    void functionA()
    {
       Lock mylock(&mu);
       ...  // 做一系列事情
    }  // mutex总是会被释放,当myloack对象从栈上被销毁的时候
    
    
    /* 结论:
     *
     * 在异常抛出后唯一保证会被执行的代码是
     * 栈上对象的析构函数
     *
     * 所以资源管理要和合适的对象生命周期结合在一起
     * 从而达到自动去分配和回收的目的
     */
    
    
    /* Note 1:
     * 另一个RAII的例子:  tr1:shared_ptr
     */
    int function_A() {
       std::tr1::shared_ptr<dog> pd(new dog()); 
       ...
    } // 当pd走出作用域时dog会被销毁 (没有指针指向pd).
    
    
    // Note 2:
    // 另一个例子:
    
    class dog;
    class Trick;
    void train(tr1::shared_ptr<dog> pd, Trick dogtrick);
    Trick  getTrick();
    
    int main() {
       // tr1::shared_ptr<dog> pd(new dog());
       train(tr1::shared_ptr<dog> pd(new dog()), getTrick());
    }
    //问题: 上面代码有什么问题?
    
    // 参数传递的操作顺序由编译器决定
    // 如果train()函数的参数传递按如下顺序进行会怎么样:
    // 1. new dog();
    // 2. getTrick();
    // 3. construct tr1::shared_ptr<dog>.
    
    // 第2步如果抛出异常,内存泄漏
    // 结论:不要将对象存到共享指针的操作跟其他声明混到一起
    
    /* Note 3:
       如果资源的管理对象被拷贝会怎样?
    */
       Lock L1(&mu);
       Lock L2(L1);
    
    /* Solution 1: 
     * 禁止拷贝. 见【不让编译器生成类函数】
     */
    
    /* Solution 2:
     * 使用tr1::shared_ptr对资源进行引用计数
     */
    
    template<class Other, class D> shared_ptr(Other * ptr, D deleter);
    
    // D的默认值是"delete":
    	std::tr1::shared_ptr<dog> pd(new dog());
    
    class Lock {
       private:
          std::tr1::shared_ptr<Mutex_t> pMutex;
       public:
          explicit Lock(Mutex_t *pm):pMutex(pm, Mutex_unlock) { 
             Mutex_lock(pm); 
          // The second parameter of shared_ptr constructor is "deleter" function.
          }; 
     }
    }
    
       Lock L1(&mu);
       Lock L2(L1);
    
  • 相关阅读:
    GZIPInputStream 流未关闭引起的内存泄漏问题
    Java ExcutorService优雅关闭方式
    redis pipline
    LeetCode 30与所有单词相关联的字串
    Scala不使用null 而使用Option,None,Some的好处
    记录: 一次解决整型溢出攻击(使用scala,隐式转换)
    Scala 封装可break和continue的foreach循环
    记录: 百度webuploader 分片文件上传java服务器端(spring mvc)示例的优化
    HBase shell 中的十六进制数值表示
    关于getSystemResource, getResource 的总结
  • 原文地址:https://www.cnblogs.com/logchen/p/10166553.html
Copyright © 2020-2023  润新知