Effective C++ 学记之13 以对象管理资源

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


两个常被使用的RAII classes分别是trl::shared_ptr和auto_ptr。前者通常是较佳选择,以为copy行为比较直观。若选择auto_ptr,复制动作会使它(被复制物)指向null。

假设一个用来塑模投资行为(股票,证券等)的程序库,其中各式各样的投资类型继承自一个root class Investment。
class Investment{...};

Investment* createInvestment();  //工厂函数,返回指针指向Investment继承体系的动态分配对象。调用者有责任删除它。

void f()
{
    Investment* pInv = createInvestment();
    ...
    delete pInv;
}

如果...区域中抛出异常、含有return语句 或者delete语句位于循环中,循环由于continue或者goto过早退出的情况下,都不能delete。
不仅是投资对象的内存被泄露,投资对象所包含的任何资源都被泄露。
为了确保createInvestment返回的资源总是被释放,把资源放进对象内,可以来c++的析构函数自动调用机制确保资源被释放。

(1)aoto_prt-》智能指针 其析构函数自动对其所指对象调用delete。
示例:
void f()
{
    std::auto_ptr<Investment> pInv( createInvestment());
    ...
}
※获得资源后立刻放进管理对象内。
“以对象管理资源”的 行为常被称为“资源取得时机便是初始化时机 RAII”
※管理对象运用析构函数确保资源被释放。
不论控制流如何离开区块,一旦对象被销毁(例如对象离开作用域)其析构函数自然会被调释放资源。

注:
①别让多个auto_ptr指向同一个对象(防止对象被删除多次);
②若通过copying函数复制auto_ptr,会变成null,而复制所得的指针将取得资源的唯一拥有权。

以上2条意味着auto_ptr并非管理动态分配资源的神兵利器。举个例子:STL容器要求其元素正常复制,因此这些容器容不得auto_ptr。

(2)auto_ptr的替代方案:RCSP 引用计数型智慧指针 reference-counting smart pointer
RCSP也是个智能指针,持续跟踪共有多少对象指向某笔资源,并在无人指向它时自动释放该资源。(类似垃圾回收)
不同的是RCSPs无法打破环状引用(例如两个其实已经没被使用的对象彼此互指)。
例:TR1的 tr1::shared_ptr
void f()
{
    ...
    std::tr1::shared_ptr<Investment> pInv( createInvestment());//shared_ptr的复制行为比auto_ptr正常
    ...
}

由于auto_ptr和shared_ptr两者都在其析构函数内做delete而不是delete[]动作,意味着动态分配而得的array身上使用auto_ptr和shared_ptr是个馊主意。
尽管如此,仍能通过编译。
std::auto_ptr<std::string> aps(new std::string[10]); //会用上错误的delete形式
std::tr1::shares_ptr<int> spi(new int[1024]);

拥有针对数组而设计,类似auto_ptr和shared_ptr的请参考:boost::scoped_array和boost::shares_array
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值