• 条款14:在资源管理类中小型coping的行为


    首先假设对于一个mutex互斥器对象,有lock以及unlock两个函数可用:

    1 void lock(Mutex * pm);
    2 void unlock(Mutex * pm);

    那么为了防止资源忘记被释放,首先得想法就是创建一个RAII类来进行资源的管理,像下面这样:

    1 class Lock{
    2     explicit Lock(Mutex * mutex)
    3     :mtx(mutex){}
    4     ~Lock(){unlock(mtx)}
    5 private:
    6     Mutex * mtx;
    7 };

    然后再用户想要使用的时候就应该这样的使用:

    1 func(mutex mtx)
    2 ...
    3 {
    4     Lock m1(&mtx);
    5 }
    6 ...
    这样是可以得,但这里应该注意的一点就是应该阻止用户无疑的对RAII类的coping行为,这个行为在这里不是我们想要的,那么可以做的基本上就是下面这几点
    1. 禁止复制:当复制确实不合理的时候就这样做
    2. 同样的,对这个RAII类的底层资源也去采用引用计数法:这里就是mtx对象了。可以将它变成shared_ptr成员。
    1 private:
    2     shared_ptr<Mutex> pMtx;
    大概就是上面这样,但是这里shared_ptr的删除含义可能不是我们想要的,我们想要在shared_ptr对象析构的时候不是去删除资源,而是去释放对mutex的占用权。
    这你就要用到shared_ptr可以自定义的删除器了,删除器在构造的时候直接可以直接的指定。
    1 class Lock{
    2 public:
    3     explicit(Mutex * pm)
    4     :pMutex(pm, unlock)
    5     {lock(pMutex.get());}//这里的get要引起注意啊
    6 private:
    7     shared_ptr<Mutex> pMutex;
    8 };
    3.复制底部的资源,就像一般一开始创造自己的string对象做的一样,复制pstring所指向的资源。
    4.转移底部资源的拥有权:这个就是auto_ptr所要做的事了,和它的意义正好的相符合的。
    小结:
    1.复制一个RAII对象就应该一并复制器所管理的资源,所以说资源的coping行为就决定了RAII对象的coping行为(就像上面这个例子中mutex的copy行为决定了他对应的RAII不应该接受拷贝)
    2.常见的RAII对象的coping行为是:抑制coping, 使用引用计数法。
     
    小结:
    1. APIs一般都要求提供原始资源,所以一般每一个RAII class都应该提供 取得所管理的资源 的方法!
    2. 显示转换一般要比隐式转换更好一点,虽然后者较为方便
  • 相关阅读:
    情感成本
    已知二叉树前序和中序,求后序
    贫穷的本质
    Centos安装docker及常见docker容器创建脚本
    SpringBoot与SpringCloud对应版本及官方查询方法
    工作流
    Host 'xxx' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
    list_layout.ini说明
    layout.ini说明
    config.ini说明
  • 原文地址:https://www.cnblogs.com/-wang-cheng/p/4856729.html
Copyright © 2020-2023  润新知