条款13(二):以对象管理资源

127 篇文章 7 订阅
39 篇文章 3 订阅

条款13:以对象管理资源

Use objects to manage resources.

RCSP

对于auto_ptr,它的替代方案是:

  • 引用计数型智慧指针(reference-counting smart pointer,RCSP)

所谓的RCSP,也是一个智能指针,持续追踪共有多少对象指向某笔资源,并在无人指向它的时候自动删除该资源。
因此,RCSP所听的行为类似于垃圾回收(garbage collection),不同之处在于RCSP**无法打破环状引用(cycles of references,例如两个其实已经没有被使用的对象彼此互指,因而呈现出它们好像还处于“被引用”的状态)。**

TR1的tr1::shared_ptr就是一个RCSP,因此可以这样构造f函数:

void f()
{
    ...
    std::tr1::shared_ptr<Investment> pInv(createInvestment());  //调用factory函数,使用pInv
    ...                                                         //经由shared_ptr析构函数会自动删除pInv
}

这段代码,和auto_ptr的版本几乎一致,但是对于shared_ptr而言,复制操作就正常了许多:

void f()
{
    ...
    std::tr1::shared_ptr<Investment> pInv1(createInvestment());    //pInv1指向createInvestment返回物

    std::tr1::shared_ptr<Investment> pInv2(pInv1);     //(copy构造)pInv1和pInv2指向同一个对象

    pInv1 = pInv2;     //(copy assignment)同上,pInv1和pInv2指向同一个对象
    ...
}       //pInv1和pInv2都被销毁,它们所指的对象也被自动销毁了

因此,由于tr1::shared_ptr的复制行为“属于正常”行为,因此它们可以被用于STL容器以及其他的“因auto_ptr的非正常赋值行为而产生不适用”的情景中。

对于auto_ptr和tr1::shared_ptr而言,二者在析构函数内实现的,都是delete而非delete[ ]动作。因此,这就意味着:

  • 不要在动态分配而得的array上使用auto_ptr或者tr1::shared_ptr。

例如,以下代码就是错误的:

str::auto_ptr<std::string> aps(new std::string[10]);//错误!使用了错误的delete

std::tr1::shared_ptr<int> spi(new int[1024]);//同样的错误

对此,并不存在特别为C++动态分配数组而设计的类似于auto_ptr或者tr1::shared_ptr这类东西,因为vector和string几乎总是可以取代动态分配而得到的数组。

另外,如果打算手工释放资源(例如使用delete而非使用一个资源管理类(resource-managing class)),这样做是很容易发生错误的。设计这样的资源管理类,需要注意很多的细节,这些内容会在条款14和15中讲到。

关于createInvestment,它所返回的是“未加工的指针(raw pointer)”,这对与资源泄漏是一个极大的隐患,因为调用者极易在这个指针身上忘记调用delete。即使使用了这一类的智能指针来执行这种delete,也必首先记的将createInvestment的返回值存储在智能指针对象内

最后:

1,为了防止资源泄漏,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放资源。

2,两个常被使用的RAII classes分别是auto_ptr和tr1::shared_ptr。一般来说,后者是较佳的选择,因为其copy行为比较直观。若选择auto_ptr,复制动作会使它(被复制物)指向null。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值