本文主要是介绍【复读EffectiveC++17】条款17:以独立语句将newed对象置入智能指针,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
条款17:以独立语句将newed对象置入智能指针
此条款,依然是针对智能指针的补充,内容分为两个部分:
- 有什么问题
- 怎么解决
一、有什么问题
取原书的例子:
写一个函数,用来揭示程序处理的优先权。
再写一个函数,用来在某动态分配得到的Widget上进行某些带有优先权的处理:
int priority();//依据”以对象管理资源“的原则,决定对动态分配的来的Widget运用智能指针,这里采用trl::shared_ptr
void processWidget(std::trl::shared_ptr<Widget> pw,int priority);
现在考虑调用processWidget,这里会出现两个问题。
1、问题一
processWidget(new Widget,priority());
但这个函数调用不能通过编译,因为在tr1::shared_ptr构造函数需要一个原始指针,但该构造函数是个explicit构造函数,无法进行隐式转换,也就是不能将“new Widget”返回的原始指针直接隐式转换为processWidget需要的tr1::shared_ptr。
2、问题二
因此用下面会通过编译的代码:
processWidget(std::trl::shared_ptr<Widget>(new Widget),priority());
虽然这样能顺利通过编译,并且使用了”以对象管理资源“,但这样调用却可能出现资源泄露。
在调用processWIdget之前,准备参数会做三件事:
- 调用 priority
- 执行 new Widget
- 调用 trl::shared_ptr 构造函数
但这里我没有对三件事进行有序排列,是因为存在一个问题,即C++编译器会以什么样的次序完成这些事情呢?
这里可以确定 执行 new Widget 一定先于 调用 trl::shared_ptr 构造函数 被调用,因为这个表达式的结果还要被传递作为trl::shared_ptr构造函数的一个实参。
但是对 调用 priority 是排在第一或第二或第三执行,就不一定了。
假设其排在第二执行,总体操作顺序将会是:
- 执行”new Widget“
- 调用priority
- 调用trl::shared_ptr构造函数
更巧的是,如果在这个过程中,对调用priority出现异常,会让第三步的调用trl::shared_ptr构造函数没有发生,new Widget调用后返回的指针不会被置入trl::shared_ptr内,造成用来防止资源泄露的机制失效。
二、怎么解决
解决方法很简单:
- 创建Widget,将它置入一个智能指针内,然后将那个智能指针传给processWidget;
代码如下:
std::trl::shared_ptr<Widget> pw(new Widget);//以智能指针存储newed所得的对象作为一条单独的语句
processWidget(pw,priority());//这个调用动作不会造成资源泄露
三、总结
以独立语句将newed对象存储于(置于)智能指针内。如果不这样做,一旦异常被抛出,有可能导致难以觉察的资源泄漏。
这篇关于【复读EffectiveC++17】条款17:以独立语句将newed对象置入智能指针的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!