3、资源管理

条款13:以对象管理资源

获得资源后立刻放进资源管理对象内 (Resource Acquisition Is Initialization RAII)
管理对象运用析构函数确保资源被释放

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

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

文中的auto_ptr已被C++11所摒弃,考虑用unique_ptr代替

条款14:在资源管理类中小心copying行为

class Lock{
public:
	explicit Lock(Mutex* pm):mutexPtr(pm){
		lock(mutexPtr);	
	}
	~Lock(){unlock(mutexPtr);}
private:
	Mutex* mutexPtr;
}

这样虽然可以保证客户在使用Lock时符合RAII,但是当发生复制时就会有问题

Lock m1(&m);
Lock m2(m1);

所以此时应该采用一定的方式去保证复制时不出问题:
1、禁止复制
2、对底层资源使用引用计数法
3、复制底部资源,即深拷贝
4、转移底部资源

复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为
普遍而常见的RAII class copying行为是:抑制copying、施行引用计数法

条款15:在资源管理类中提供对原始资源的访问

std::tr1::shared_ptr<Investment> pInv(createInvestment());
int daysHeld(const Investment* pi);

这种情况下,使用资源管理类造成API无法调用。
所以资源管理类应该提供对原始资源的访问。
1、显式转换

class Investment{
public:
	InvestmentHandle* get() const{return mInvest;}
}

通过get函数返回原始资源
2、隐式转换

class Investment{
public:
	operator InvestmentHandle*() const{return mInvest;}
}

通过重载operator()提供隐式转换来返回原始资源。

APIs往往要求访问原始资源,所以每一个RAII class应该提供一个取得原始资源的办法
对原始资源的访问可能经由显式转换或隐式转换。一般而言显式转换更安全,但隐式转换更方便

条款16:成对使用new和delete时要采取相同形式

用new[]申请内存的话就要用delete[]去释放。用new申请内存的话就用delete去释放

条款17:以独立语句将newed对象置入智能指针

int priority();
void processWidget(std::tr1::shared_ptr<Widget> pw, int priority)

调用时如果采用这种方式:

processWidget(new Widget, priority());

编译不通过,因为tr1::shared_ptr的构造函数是explicit,不允许隐式转换。
可以改为下面的方式

processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());

但是此方式有可能会出现问题:
因为编译器对 priority()、new Widget和tr1::shared_ptr构造函数三个的执行顺序不一定,有可能出现先执行new Widget 再执行priority()最后执行tr1::shared_ptr构造函数。这时如果priority()出现异常,那个new Widget返回的指针就变成了野指针。

所以要这么写

std::tr1::shared_ptr<Widget> pw(new Widget);
processWidget(pw, priority());

以独立语句将newed对象置入智能指针内。如果不这样做,一旦抛出异常,有可能会造成内存泄漏。

虽然本章内容大部分已被C++11解决,但是本章的思想还是值得学习的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值