【无标题】effective c++ 笔记(3)

13用对象管理资源

  • 为防止资源泄露,使用RAII(资源获取时机就是初始化时机)对象,在构造函数中获得资源,析构函数中释放资源
  • 使用uniuqe_ptr or shared_ptr 文中提到的auto_ptr 在c++11中被废弃了
    考虑在以下代码中
void foo(){
	base* B =  factory(); //获取到资源
	...
	delete B; //释放资源
}

若在…中出现异常抛出等问题,那么delete B就不是一定被执行,造成内存泄漏,因此考虑使用对象进行管理,在程序离开作用域时,对象就会自动被析构

void foo(){
	share_ptr<Base> shp(factory()); //获取到资源
	...
	
}

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

考虑以下代码,使用一个Lock类对互斥锁mutex进行管理

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

看起来非常合理,但是如果发生copy会怎么样?

Mutex m;
Lock m11(&m);
Lock m12(m11);

以下几种方式:

  • 禁止复制,如条款6将copy操作声明为private
  • 使用‘引用计数法’,使用shared_ptr,指定删除器,因为如果shared_ptr引用为0时,会默认将资源删除,如果是锁一类的资源,可以指定删除器函数为unlock,在引用为0时调用指定删除器
  • 对资源进行深拷贝
  • 前两条更普遍

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

  • 有两种方式,提供显示转换或者隐式转换,其中显示转换更安全,隐式转换对客户比较方便

考虑一个使用于字体资源的RAII类,由于经常需要访问原始资源Fonthandle,需要经常将Font转换为Fontheadle,

Fonthandle getFont(); //简化参数,获取一个Fonthandle
void releaseFont(Fonthandle fh);
class Font{
public:
	explicit Font(Fonthandle fh):f(fh){}
	Fonthandle get(){ return f;}//提供显示转换函数
	operator FontHandle() const{ return f;}//隐式转换函数
	~Font(){releaseFont(f);}
private:
	FontHandle f;
}

void changeFontSize(Fonthandle fh, int newSize);
Font f(getFont());
int newSize;

changeFontSize(f.get(),newSize)//显示转换
changeFontSize(f,newSize)//隐示转换

16 成对使用new和delete要保证形式相同

  • 许多编译器实现数组和单个对象的内存分布,通常是在数组的前几位bit存储,此数组有多少个对象,因此如果对数组指针使用delete,以及对普通对象指针使用delete [] ,都是未定义行为
  • 不要对数组使用typedef。

17 以独立语句将newed对象放入智能指针

int someOper();
voif processWidget(shared_ptr<Widget> pw, int someOper());

processWidget(shared_ptr<Widget>(new Widget), someOper());//1.不推荐

shared_ptr<Widget> pw(new Widget);//2.
processWidget( pw, someOper());//3.
  • 不推荐1处做法 共完成三件事
  1. 执行new Widget
  2. 调用shared_ptr构造函数
  3. someOper()
  • 对于这三件事的执行顺序没有明确定义,但是1一定在2后面,如果出现执行顺序是,132,且3抛出异常了,那么就会出现资源泄露,因此推荐将new对象和放入智能指针分开写。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值