所谓资源,就是一旦使用它,将来必须还给系统。
条款13:以对象管理资源
在一般函数中释放资源以一定的弊端,如函数为执行或函数发生异常。以对象管理资源最常用的方法就是智能指针。
条款14:在资源管理类中小心copying行为
对于以个资源管理类,当复制对象时,资源管理类的动作可能是以下几种;
(1)禁止复制:如果复制行为不合理。
(2)对底层资源使用“引用计数”:可以使用智能指针,但是有时需要传递自定义的“删除器”,因为,当引用计数为0时不一定是删除对象。(例如解绑定)
(3)复制底部资源:“深度拷贝”。
(4)转移底部资源的管理权。
条款15:在资源管理类中提供对原始资源的访问
此条款的主要原因是有时函数需要的指针是内置指针,这时传递资源管理类定义的指针(智能指针)编译器无法通过编译,所以,
(1)资源管理类提供智能指针向内置指针的转换。(显式)
例如智能指针提供了一个get()函数,返回函数智能指针的内置类型指针。
(2)提供隐式类型转换函数。但是这种做法很容易产生不想发生的转换
两种做法的判断标准是:接口容易使用,不易被误用。
条款16:成对使用new和delete时要采用相同的形势
此条款主要讲述指针数组的delete[]的情况。
条款17:以独立语句将newed对象置入智能指针
考虑下面这个问题:
函数:
int priority();
void processwidget(shared_ptr<widget>pw,int priority);
如此调用void processwidget(shared_ptr<widget>(new widget),priority());
可能会发生资源泄露!!!
原因:C++编译器对于上述调用,会有三个部分
(1)执行“new widget”表达式;
(2)调用shared_ptr构造函数;
(3)调用priority。
但是编译器对上面三个部分却没有固定的发生顺序,虽然,(1)一定发生在(2)之前,但是(3)的顺序却不确定,问题就可能出现在这里。如果(3)发生在(1)(2)之间,且(3)调用异常,此时new的资源就会泄露,智能指针没能起到释放资源的作用。
解决方法很简单:分离语句,
先创建shared_ptr<widget>pw(new widget);
然后调用processwidget(pw,priority());
这样编译器就没有权利去调整语句间的顺序了。