Item 17:在单独的语句中将new的对象放入智能指针

在单独的语句中将new的对象放入智能指针

在单独的语句中将new的对象放入智能指针,这是为了由于其他表达式抛出异常而导致的资源泄漏。 因为C++不同于其他语言,函数参数的计算顺序很大程度上决定于编译器。

processWidget(shared_ptr<Widget>(new Widget), priority());

上述代码中,在processWidget函数被调用之前参数会首先得到计算。可以认为包括三部分的过程:

  • 执行new Widget
  • 构造shared_ptr<Widget>
  • 调用priority()

多数情况下编译器有权决定这三部分过程的顺序,如果很不幸由于某种效率原因,执行顺序变为:

  • 执行new Widget
  • 调用priority()
  • 构造shared_ptr<Widget>

但是请考虑,如果对 priority 的调用引发一个异常将发生什么。在这种情况下,从 "new Widget" 返回的指针被丢失,因为它没有被存入我们期望能阻止资源泄漏的 shared_ptr。由于一个异常可能插入资源创建的时间和将资源交给一个资源管理对象的时间之间,所以调用 processWidget 可能会发生一次泄漏。

避免类似问题的方法很简单:用一个单独的语句创建 Widget 并将它存入一个智能指针,然后将这个智能指针传递给 processWidget:

std::tr1::shared_ptr<Widget> pw(new Widget);  
processWidget(pw, priority());               

这样做是因为编译器在不同的语句之间重新安排操作顺序的活动余地比在一个语句之内要小得多。"new Widget" 表达式和 shared_ptr 的构造函数的调用与 priority 的调用在不同的语句中,所以编译器不会允许 priority 的调用插入它们中间。

总结

  • 在一个独立的语句中将 new 出来的对象存入智能指针。如果疏忽了这一点,当异常发生时,可能引起微妙的资源泄漏。
posted @ 2020-01-15 09:44  刘-皇叔  阅读(143)  评论(0编辑  收藏  举报