《Effective C++》学习笔记——条约17

《Effective C++》学习笔记——条款17

***************************************转载请注明出处: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.有什么问题吗?

当然会出现问题,如果这三个动作的顺序是这样的:

1.执行 "new Widget"

2.调用 priority 

3.调用 tr1::shared_ptr 构造函数


如果 在第二个 步骤 出现错误,导致异常,会怎么样? 第一步返回的指针将会丢失,造成资源泄漏。Oh No! 这一大章,我们一直在管理资源,与这些问题斗争,这里又出现了资源泄漏!



4.所以,要这样解决

解决办法也异常简单,不要嫌麻烦,写两行。(就是把一句话分开成两句来写)

因为,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********************************************