Effective C++ rule 14 在资源管理对象中处理好copy行为
来源:互联网 发布:通联数据 公司怎样 编辑:程序博客网 时间:2024/06/05 22:32
前言
上节说到,为了能够方便的管理资源,达到自动释放资源的目的,我们提出了使用栈对象管理资源的思想。其中,上一节我们重点介绍了如何处理动态内存资源。但是处理动态分配的内存资源外,还有一些其他的资源,例如 互斥锁/信号量,文件描述符,等等,这些东西有自己的特有的资源管理需求。互斥锁需要在离开临界区时及时unlock,而不是像内存管理那么delete掉。这个时候就需要我们自己定制资源管理类了。
然后,自己定制资源管理类时,要特别注意类的复制函数的行为。
举个例子
Code1.1
#include <stdio.h>#include <stdlib.h>class Lock{public: Lock(mutex *pm) :mutexPtr(pm) { lock(pm); } ~Lock() { unlock(mutexPtr); }private: mutex *mutexPtr;};
这个Lock简单的对互斥锁进行管理,能够实现互斥锁在离开作用域是的自动解锁。但是如果存在这样的语句:
Mutex m;Lock ml(&m);Lock m1(m2);
会发生怎么样的事情呢?默认的编译器会将m1的mutexPtr指针复制给m2的mutexPtr,这样就会有两个对象去指向互斥锁m。这个时候将会出现m1与m2被回收后,m解锁两次的问题。
然而,我们并不希望发生这样的事情,那么这个时候就需要我们手动的指定复制函数行为,包括复制构造函数以及赋值运算符。我们可以把Lock设计为无法复制的。例如:
Code1.2
#include <stdio.h>#include <stdlib.h>class Lock{public: Lock(mutex *pm) :mutexPtr(pm) { lock(pm); } ~Lock() { unlock(mutexPtr); }private: Lock(const Lock & rhs) { ; } Lock& operator=(const Lock&rhs) { ; }private: mutex *mutexPtr;};
常见的处理方式
一般来说,在为资源管理对象编写复制函数(复制构造函数,赋值运算)时主要有以下的策略:
禁止复制。
如果复制资源是不合理的,那么我们可以禁止资源管理对象之间的复制。这主要是将类的复制构造函数和赋值运算符定义为private即可。例如Code1.2所示的方法。
使用“引用计数法”
有时候,我们希望保有资源,直到它的最后一个使用者被销毁时。举个应用场景:某些动态分配的内存,可能会有多个指针指向同一个动态资源,大部分时候我们希望直到指针都不在指向该资源是再释放该资源。这个时候就需要使用“引用计数法”。这个使用shared_ptr作为资源管理器的其中一个变量即可。
Code1.3
#include <stdio.h>#include <stdlib.h>#include <iostream>#include <xstddef>#include <memory>using namespace std;class Lock{public: explicit Lock(mutex *pm) :mutexPtr(pm, unlock) { lock(pm); } ~Lock() { unlock(mutexPtr); }private: shared_ptr<mutex> mutexPtr;};
允许复制,而且支持深度复制
这个比较好理解,进行深度复制。
转移控制权
有时,我们允许资源类间的复制,但是复制意味资源控制权的转移,比如auto_ptr指针的做法。例如:
Code1.4
#include <stdio.h>#include <stdlib.h>class Lock{public: Lock(mutex *pm) :mutexPtr(pm) { lock(pm); } ~Lock() { unlock(mutexPtr); } Lock(Lock & rhs) { if (this == &rhs) return ; mutex * temp = rhs.mutexPtr; rhs.mutexPtr = NULL; mutexPtr = temp; } Lock& operator=(Lock&rhs) { if (this == &rhs) return *this; mutex * temp = rhs.mutexPtr; rhs.mutexPtr = NULL; mutexPtr = temp; return *this; }private: mutex *mutexPtr;};
总结
在自己编写资源管理类的时候,要特别关注copy函数的编写,要弄清楚所管理的资源需要什么样的copy行为。
- Effective C++ rule 14 在资源管理对象中处理好copy行为
- 【Effective c++】条款14:在资源管理中小心copying行为
- Effective C++(14) 在资源管理类中小心copying行为
- Effective C++:条款14:在资源管理类中小copying行为
- 《Effective C++》学习笔记条款14 在资源管理类中小心拷贝行为
- Effective C++——》条款14:在资源管理中小心copying行为
- 读书笔记《Effective C++》条款14:在资源管理类中小心copying行为
- C++之在资源管理类中小心copying行为(14)---《Effective C++》
- effective c++ 在资源管理类中小心copying 行为
- Effective c++学习笔记条款14:在资源管理类型中小心copying行为
- Effective C++ 学记之14 在资源管理类中 小心 copying行为
- Effective C++ Item 14 在资源管理类中小心copying行为
- Effective C++ Item 14-在资源管理中小心的copying行为
- 《Effect C++》学习------条款14:在资源管理类中小心coping行为
- Effective C++读书笔记之十四:在资源管理类中小心copying行为
- 条款14:在资源管理中心小心copy行为之重难点
- 条款14: 在资源管理类中小心copying行为
- 条款14、 在资源管理类中小心copying行为
- Kafka到SparkStreaming的两种方式
- 编程练习——数字颠倒
- 关于i--与System.out.println()联合使用时可能出现的异常情况
- Windwos Server 2012 R2 部署iSCSI 虚拟存储
- KMP详解
- Effective C++ rule 14 在资源管理对象中处理好copy行为
- 基于距离变换和分水岭算法的图像分割(图像变换 )
- eclipse中git用本地或线上分支完全覆盖本地分支——reset
- A
- spring boot 切换redis数据库
- ios-给UIViewController设置背景图
- C“段错误” : scanf(struct1->struct2->num)报段错误
- 欢迎使用CSDN-markdown编辑器
- ANSYS 8.0完美破解完整版\