zoukankan      html  css  js  c++  java
  • 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);
    
  • 相关阅读:
    Linux 设置秘钥登录(SSH免密远程登录)
    maven profile动态选择配置文件
    PKU 1521 Entropy(简单哈弗曼树_水过)
    POJ 3253 Fence Repair(简单哈弗曼树_水过)
    XDU 1001 又是苹果(状态压缩)
    PKU 3318 Matrix Multiplication(神奇的输入)
    PKU 3318 Matrix Multiplication(随机化算法||状态压缩)
    PKU 2531 Network Saboteur(dfs+剪枝||随机化算法)
    PKU 1035 Spell checker(Vector+String应用)
    PKU 2002 Squares(二维点哈希+平方求余法+链地址法)
  • 原文地址:https://www.cnblogs.com/logchen/p/10166553.html
Copyright © 2011-2022 走看看