***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************
三、Resource Management
Rule 17:Store newed objects in smart pointers in standalone statements
规则 17:以独立语句将
newed 对象置入智能指针
1.现象
我们要让程序有优先权,所以要用一个函数在 动态分配获得的对象上附带 优先权。
<span style="font-family:Comic Sans MS;">int priority();</span>
<span style="font-family:Comic Sans MS;">void processWidget(std::tr1::shared_ptr<Widget> pw, int priority);</span>
要知道,我们不能这样用:
processWidget( new Widget , priority() );
而是应该这样:
processWidget( std::tr1::shared_ptr<Widget>( new Widget ) , priority() );
2.编译器会怎么做?
编译器产出 processWidget 调用码之前,必须核算每个实参。 processWidget 第二个参数很简单,只是单纯调用函数,而第一个参数就不一样了,它是两个动作:
->调用 new Widget 表达式
->调用 tr1::shared_ptr 构造函数
所以,在调用processWidget 函数之前, 编译器必须做下面三件事:
> 调用 priority
> 执行 " new Widget "
> 调用 tr1::shared_ptr 构造函数
问题是,C++编译器 以什么顺序 执行这三件事,是难以判断的。它不像C#、JAVA 有特定的次序执行动作。在C++ ,你只能确定,new Widget 动作 优先于 tr1::shared_ptr 动作。
3.有什么问题吗?
当然会出现问题,如果这三个动作的顺序是这样的:
4.所以,要这样解决1.执行 "new Widget"
2.调用 priority
3.调用 tr1::shared_ptr 构造函数
如果 在第二个 步骤 出现错误,导致异常,会怎么样? 第一步返回的指针将会丢失,造成资源泄漏。Oh No! 这一大章,我们一直在管理资源,与这些问题斗争,这里又出现了资源泄漏!
解决办法也异常简单,不要嫌麻烦,写两行。(就是把一句话分开成两句来写)
因为,C++ 编译器 无法跨越 语句进行重新排列,只能在语句内重新排列,上面那个问题就该这样写:
<span style="font-family:Comic Sans MS;">std::tr1::shared_ptr<Widget> pw( new Widget ) processWidget(pw,priority() );</span>
5.最后,请记住
★ 以独立语句将 newed 对象存储于(置入)智能指针内。如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄漏。
***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************
原文地址:http://blog.csdn.net/lttree/article/details/41751287