Effective C++之条款13:以对象管理资源

声明:

  1. 文中内容收集整理自《Effective C++(中文版)第三版》,版权归原书所有。
  2. 本内容在作者现有能力的基础上有所删减,另加入部分作者自己的理解,有纰漏之处敬请指正。

条款13:以对象管理资源

Use objects to manage resources.

现在假设用一个类来模拟投资行为,各式各样的投资类都继承自一个基类Investment。

class Investment{...}; //基类

用工厂函数来创建特定的Investment对象:

Investment* createInvestment();

createInvestment的调用端使用了函数返回的对象之后,有责任删除之,如下函数履行了这个责任:

void f()
{
    Investment* pInv=createInvestment();
	...
    delete pInv;//释放资源
}

这看起来妥当,但我们不能保证任何情况下都能够执行到delete pInv语句。所以,单纯依靠delete来删除远远不够。

为确保createInvestment返回的资源总是被释放,我们需要将资源放进对象内,当控制流离开f,该对象的析构函数会自动释放那些资源。把资源放进对象内,我们便可倚赖C++的“析构函数自动调用机制”确保资源被释放。

许多资源被动态分配于heap内而后被用于单一区域内,当控制流离开那个区域或者函数时被释放。标准库里提供了一些指针,正是针对上面这种情况的。auto_ptr是个“类指针对象”,也就是所谓的“智能指针”,其析构函数自动对其所指对象调用delete。

void f()
{
	std::auto_ptr<Investment> pInv(createInvestment());
	//经由auto_ptr的析构函数自动删除pInv
	...
}

上面以资源管理对象体现了两个关键想法:

  1. 获取资源后立即放进管理对象。资源获取即初始化(resource acquisition is initialization, RAII)。获取资源后立即放进对象内进行管理。以上代码中createInvestment返回的资源被当做其管理者auto_ptr的初值。
  2. 管理对象运用析构函数确保资源释放。

由于autpo_ptr被销毁时会自动删除它所指之物,所以一定不要让多个auto_ptr同时指向同一对象。auto_ptr指针会有资源的唯一使用权。auto_ptr有个不同寻常的性质:当auto_ptr指针通过copy构造函数或copy assignment操作符给其他指针赋值时,它们将会变成null,而复制所得的指针将取得资源的唯一拥有权。

由于对资源的唯一使用权的这个行为使得auto_ptr使用比较受限。例如STL容器中的元素不能使用auto_ptr。

auto_ptr的替代方案是“引用计数器型智能指针”(refercence-counting smart pointer, RCSP)。它会记录有多少个对象在使用资源,当使用资源的计数器为零时,就会释放资源。

void f()
{
	...
	std::tr1::shared_ptr<Investment> pInv(createInvestment());
	//经由auto_ptr的析构函数自动删除pInv
	...
}

由于tr1::shared_ptr的复制行为“一如预期”,它们可以被用于STL容器。

注意:auto_ptr和shared_ptr两者都是在其析构函数内执行delete而不是delete[],所以不能用于动态分配的数组。

//下面这两个都是馊主意
std::auto_ptr<std::string> aps(new std::string[10]);
std::tr1::shared_ptr<int> spi(new int[1024]);

最后还要说明一点:createInvestment返回的是未加工指针(raw pointer),调用者极易忘记释放,即便是使用智能指针,也要首先把CreateInvestment()返回的指针存储于智能指针对象内。条款18将对其进行讨论。

请记住:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值