《Effective C++》Item17:使用独立的语句将底层资源放入RTTI对象中

假设现在我们有一个函数用来处理程序的优先级,另一个函数用来在某个动态分配所得的对象上进行一些带有优先级的处理:

int priority();
void processObject(std::shared_ptr<Object> obj, int priority);

由于我们时刻牢记“使用对象管理资源”的智慧铭言,因此决定对动态分配获得的对象使用智能指针。

现在考虑如何来调用processObject函数:

processObject(std::shared_ptr<Object>(new Object), priority());

令人惊讶的是,虽然我们在这里使用了RTTI对象来管理资源,这条语句仍然可能会导致资源泄露。

编译器在处理上面这条语句时,必须首先核算即将被传递的各个实参;上述的第二个实参只是一个单纯的priority函数调用,但是第一个实参却由两部分组成:

  • 执行new Object语句。
  • 执行std::shared_ptr的构造函数。

于是我们在调用processObject之前,编译器必须要进行如下操作:

  • 调用priority函数。
  • 执行new Object语句。
  • 调用std::shared_ptr的构造函数。

问题在于,C++编译器应该以什么样的次序来完成这些事情呢?弹性很大。这和JavaC#这类编程语言不同,这两种高级语言总是以特定的次序完成函数参数的核算。但是对于C++而言,我们仅能保证:new Object一定会在shared_ptr的构造函数之前被执行,而priority函数的调用位置则可以是任意的:它可能在上面两条语句的中间被执行,这完全取决于编译器。

一旦这种情况发生,那么就要思考:如果priority函数抛出了异常,会发生怎样的情况?此时new Object返回的指针会遗失,因为它尚未来得及被放入RTTI对象中;也就是说,但就这一条语句,也是有可能发生资源泄露的。

避免这个问题的方式很简单:将语句分离开,分别写出new Object、将指针放入RTTI对象的语句和函数调用语句

std::shared_ptr<Object> obj(new Object);
processObject(obj, priority()); 

这样,编译器就无法对这些语句进行重新排列了,只有按照我们要求的合理的次序依次执行,从而避免了资源泄露。

【注意】
使用独立的一条语句将底层资源放入RTTI对象中;如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄露。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值