【复读EffectiveC++13】条款13:以对象管理资源

本文讲述了在C++编程中,为何采用类进行资源管理,如何通过RAII原则实现自动资源释放,以及介绍了auto_ptr和shared_ptr这两种智能指针的使用方法。特别强调了避免资源泄漏的重要性,提倡使用shared_ptr作为首选的资源管理工具。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

条款13:以对象管理资源

此条款,针对对象管理,内容分为三个部分:

  • 为什么用类管理
  • 怎么用类管理
  • 有什么要注意的

一、为什么用类管理

解释为什么用,可以用一个反例来衬托用类管理的好,即一个原书中的例子:

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

void f()
{
	Investment* pInv = createInvestment(); // 调用factory函数
	...
	delete pInv; // 释放pInv所指的对象
}

这种程序设计的缺陷主要在于我们可能无法释放获取的pInv对象:

  • 如果在delete之前有return语句导致函数执行结束,那么对象就无法释放。
  • 如果在delete之前程序抛出异常,那么也无法释放对象。
  • 如果这段代码在之后软件开发维护过程中被修改,那么后人可能无法知道要释放这个pInv对象,因为单纯的靠函数f中的delete语句来释放对象是行不通的。

二、怎么用类管理

用类管理的核心思想就是RAII,即 Resources Acquisition Is Initialzeation,指资源取得的时机便是初始化时机,重点是自动处理资源

具体处理思路为获得资源后立刻放进管理对象内,使用类性质达到自动处理资源的效果,确保管理对象能运用析构函数使得资源被释放,其代表就是智能指针(auto_ptr 和shared_ptr)。

但是如果析构函数抛出异常,可能需要自己手动处理,参考条款8的析构异常处理。

C++程序库提供了两种类,更加安全的管理自己的资源,分别是:shared_ptr和auto_ptr(现在它已经被unique_ptr替代)。

1、auto_ptr

auto_ptr是个智能指针,其析构函数自动对其所指对象调用delete,但此智能指针是存在唯一性的,即赋值操作后智能指针失效,保证同时最多一个智能指针指向管理对象

void f()
{
    //调用函数获得对象
    std::auto_ptr<Investment> pInv(createInvestment());
 	... 
}//函数执行完之后,auot_ptr的析构函数自动删除pInv
//获得一个对象,并管理该对象
std::auto_ptr<Investment> pInv1(createInvestment());
 
//拷贝pInv1,此时pInv1被设为null,现在pInv2管理这个资源
std::auto_ptr<Investment> pInv2(pInv1);
 
//赋值操作,此时pInv2变为null,现在pInv1管理这个资源
pInv1 = pInv2;

2、shared_ptr

shared_ptr也是智能指针,但是其与autp_ptr不同,其是“引用计数型智能指针”(RCSP),也就是多个shared_ptr可以同时指向一个管理对象,只有当没有shared_ptr指向管理对象(引用计数为0),才会销毁。

三、有什么要注意的

C++没有为动态分配数组而设计的智能指针类,是因为C++已经有了vector和string这样的管理类,这些类已经够我们使用了,因此提供动态分配数组管理的类是多余的

但是Boost库中的boost::scoped_array和boost::shared_array类是接近于为数组而设计的类,因此你们想要了解的话,可以参阅这两个类。

//都是错误的
std::auto_ptr<std::string> aps(new std::string[10]);
std::shared_ptr<int> aps(new int[1024]);

四、总结

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

两个常被使用的RAII类分别是tr1::shared_ptr和auto_ptr(以抛弃不再使用)
shared_ptr通常是较佳选择,因为其拷贝行为比较直观
auto_ptr复制动作会使它(被复制对象)指向null

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值