EffectiveC++-条款17:以独立语句将newed对象置入智能指针

一. 内容

  1. 令人惊讶的是,即使我们使用对象管理资源,下面代码仍存在泄漏资源。

    inline Resource* GetResource() {
        return new Resource(1);
    }
    inline void OtherProgress(std::shared_ptr<Resource> Resource, int Priority) {}
    
    inline void UseResource() {
        OtherProgress(std::shared_ptr<Resource>(GetResource()), GetPriority(100));
    }
    
  2. 编译器在产出 OtherProgress 调用码之前,需要核算每一个被传递的实参。上述第二实参只是一个单纯的返回优先级函数,但是第一实参由两部分组成:

    • 执行 new Resource 表达式
    • 调用 shared_ptr 构造函数

    这意味着在调用 OtherProgress 之前,要做这三件事。
    但是编译器并不保证这三件事情的次序。这和其他语言如Java,C#不同,那两种语言总是以特定的次序完成函数的核算。如果编译器为了更高效的代码,那么它们的调用次序不一定是按实参的次序。可能:

    • 执行new Resource表达式
    • 调用GetPriority函数
    • 调用shared_ptr构造函数

    假如是按这种方式,如果对调用 GetPriority 函数时出现异常,会发生什么事情,new Resource 返回的资源尚未置入 shared_ptr 智能指针,也就是未进入我们防卫资源泄漏的武器。
    这种由于核算实参次序导致的问题可以很简单的被避免:使用分离语句,先创建Resource,再调用OtherProgress。

    inline void OtherProgress(std::shared_ptr<Resource> Resource, int Priority) {}
    
    inline void UseResource() {
        const std::shared_ptr<Resource>ResourcePointerOne(GetResource());
        OtherProgress(ResourcePointerOne, 100);
    }
    

这样,编译器不能再重新排列这些跨语句的各项操作,从而促使事件向我们期望的方向发展。

二. 总结

  1. 以独立语句将 newed 对象存储于(置入)智能指针内。如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄漏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值