《Effective C++》读书笔记 资源管理
C++程序中最常用的资源包括动态分配的内存,文件描述器,互斥锁,数据库连接,网络socket等等。不论哪种资源,重要的是,当你不再使用他时,必须将他归还给系统。
一个很好的做法是以对象管理资源。把资源放进对象内,我们便可依赖C++的析构函数自动调用机制确保资源被释放,这样便不会发生资源泄露的问题。一个实现的方法是,以智能指针封装资源,由于atuo_ptr缺陷太多,已经基本被废弃,建议使用shared_ptr。下面看一个使用shared_ptr的具体实现
-
void f()
-
{
-
shared_ptr<Investment> pInv(createInvestment());//工厂函数返回的对象初始化资源,再用shared_ptr封装他
-
}
shared_ptr的一个特性是其提供了引用计数,每当其管理对象被指向便会+1,在无人指向它时自动删除该资源,并且支持copy操作。因为可以很方便的通过它进行内存管理,不用担心资源泄露。
在资源管理类中小心copying行为
一般情况下,对资源的复制行为是不会允许的,比如互斥锁,你不会想要把一个互斥器对象复制的,对吧?所以如果你的资源对象不适合被复制,你应该禁止复制这种行为:把copying操作声明为private,然后继承它,就像下面这样
-
class Lock:private Uncopyable
-
{
-
...
-
};
或者如果你确实有需求复制资源,例如你非得复制互斥器,那就使用前面介绍的shared_ptr吧,但是shared_ptr有一个不幸的特性,当引用次数为0时删除其所指物,不过类似于C++标准库里的其他部件,shared_ptr允许你定制自己的删除器,shared_ptr有一个重载类型接受第二个参数。
-
Class Lock
-
{
-
public:
-
explicit Lock(Mutex* pm):mutexPtr(pm,unlock)//第二个参数指定引用计数为0时的行为,即是unlock
-
{
-
lock(mutexPtr.get());//mutexPtr.get()返回mutexPtr管理对象的原生类型
-
}
-
private:
-
shoread_ptr<Mutex> mutexPtr;
-
};
在资源管理类中提供对原始资源的访问也是一个重要的功能。
对于share_ptr,它提供了get()成员函数,用来执行显式转换,返回智能指针内部的原始指针
对与我们自定义资源管理类,有两种方式提供对原始资源的访问:显式转换函数和隐式转换函数
-
//假设我们有这样一个类
-
class Font
-
{
-
public:
-
explicit Font(FontHandle fg):f(fh){}
-
private:
-
FontHandle f;
-
};
其显式转换函数形式为
FontHanld get() const { return f; }
其隐式转换函数形式为
operateor FontHandle() const { return f; }
这两种形式各有好处,隐式转换的好处是比较自然,但是会增加错误发生机会,例如我们本想得到一个Font,结果却意外得到FontHandle
-
Font f1(getFont());
-
FontHandle f2=f1;//这里会将Font转型为FontHandle,假如这不是你想要的呢?这个错误很隐蔽
在使用智能指针时会发生一个问题,如果有一个函数是以下形式:
process( shared_ptr<Investment> (new Investment),priority );
这条语句有三个动作:
调用unlock,执行new Investment,调用shared_ptr构造函数。我们知道,new Investment动作一定在shared_ptr构造函数之前,另外C++对构造函数内动作的次序是无定义的,如果unlock动作发生在第二顺位,并且如果它的调用导致异常,此时new Investment返回的指针会遗失,引发资源泄露。对此,解决方法是先建立好智能指针。
-
shared_ptr<Investment> p(new Investment);
-
process(p,priority);
总结起来便是,以独立语句将newed对象置入智能指针。
最新文章
- poj1006 / hdu1370 Biorhythms (中国剩余定理)
- JS数组键值,数组合并,
- Spring—Quartz定时调度CronTrigger时间配置格式说明与实例
- Windows 10 解决 0x80070021 错误
- usb库文件usb_desc.c分析
- Expression<;Func<;T,TResult>;>;和Func<;T,TResult>; 与AOP与WCF
- 20151120 jsp相关
- css3动画工具
- 记录下关于SQL Server的东西
- AI 人工智能 探索 (三)
- Java容器---Map基础
- Sequelize 基本操作
- Spring Cloud 入门教程 - Eureka服务注册与发现
- PHP学习笔记 02 之文件上传
- WebSocket刨根问底(二)
- [转]js 取得 Unix时间戳(Unix timestamp)
- 数据备份、pymysql模块
- PHP实现简单发红包(随机分配,平均分配)
- Concordion test
- 如何在Android的ListView中构建CheckBox和RadioButton列表(支持单选和多选的投票项目示例)