Effective C++ T13:以对象管理资源

38 篇文章 0 订阅
31 篇文章 2 订阅

Effective C++学习笔记总链接

改善程序与设计的55个具体做法学习笔记-每日1条


条款13:以对象管理资源

【技巧】

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

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


C++ 程序中常见使用的资源就是动态分配内存(如果你分配内存却从来不曾归还它,会导致内存泄漏)

Factory(工厂)函数:放回一个base class指针,指向新生成的derived class对象

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

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

【问题】:“…” 区域内的可能过早的return或者抛出异常,导致delete被略过去,从而泄漏数据。

【解决思路】:为了确保createInvestment()返回的资源总被释放,我们需要将资源放进对象内,当控制流离开f,该对象的析构函数会自动释放那些资源。

【注意】:许多资源被动态分配与heap内而后被用于单一区块或函数中,它们应该在控制流离开那个区域或函数时被释放

auto_ptr

标准程序库提供auto_ptr,是个类指针对象,为“智能指针”,析构函数自动对其所指对象调用delete

使用auto_ptr避免f函数潜在的资源泄漏的可能性,代码如下

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

由于auto_ptr被销毁时会自动删除它所指的对象,一定要注意:别让多个auto_ptr同时指向同一对象。 对象被删除一次以上,程序会有未定义行为

auto_ptr有个性质:若通过copy构造函数或copy assignment 操作符复制它们,它们会变为null,而复制所得的指针将取得资源的唯一拥有权

std::auto_ptr<Investment> pInv1(createInvestment()); // pInv1指向
													 //createInvestment返回物

std::auto_ptr<Investment> pInv2(pInv1); // 现在pInv2 指向对象, pInv1被设为null

pInv1 = pInv2; // 现在pInv1 指向对象,pInv2 被设置为null

性质:受auto_ptr管理的资源必须绝对没有一个以上的auto_ptr同时指向它

以对象管理资源关键想法

1. 获得资源后立刻放进管理对象内

以上代码createInvestment 返回的资源当做其管理者auto_ptr的初值

实际上,“以对象管理资源”常被称为“资源取得时机便是初始化时机"(Resource Acquisition Is Initialization; RAII)” ,因为总是在获得一笔资源后于同一语句内,以它初始化某个管理对象。

2. 管理对象运用析构函数确保资源被释放

不论控制流如何离开区块,一旦对象被销毁,其析构函数自然会被自动调用,于是资源被释放。

shared_ptr(RCSP)更好的方案

auto_ptr的替代方案为“引用计数型智慧指针”(reference- counting smart pointer,RCSP

RCSP也是个智能指针,持续追踪共有多少对象指向某个资源,并在无人指向它时自动删除该资源

shared_ptr就是个RCSP

代码如下

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

auto_ptr 和 shared_ptr两者都是其析构函数中做delete而不是delete[]动作。意味着在动态分配而得到array身上使用auto_ptr 和 shared_ptr是个馊主意

std::share_ptr<std::string> aps(new std::string[10]); //馊主意,会用上错误的delete形式

createInvestment 返回的“未加工指针”(raw pointer)简直是对资源泄漏的一个死亡邀请,因为调用者极易在这个指针身上忘记调用delete。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值