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

对于资源管理类而言,有时候你需要处理原始资源(raw resources)的访问。当你使用智能指针如auto_ptr或tr1::shared_ptr保存资源类的时候。当你需要访问智能指针指向的原始资源的时候,你有显示转换和隐式转换两个方法:显示使用智能指针的get函数,隐式方法智能指针重载了指针的取值操作符(operator->和operator*)。

有时候必须取得RAII对象内的原始资源,某些RAII class设计者做法是提供隐式转换函数,考虑如下的用于字体的RAII class(对C API而言字体是一种原生数据数据结构):

FontHandle getFont(); //C API
void releaseFont(FontHandle fh); //C API

class Font
{
public:
	explicit Font(FontHandle fh):f(fh){}
	~Font(){ releaseFont(f);}
private:
	FontHandle f;
};

假设有大量与字体相关的C API,它们处理FontHandle,那么将Font转换成FontHandle会是一种很频繁的需求,Font可能会提供显示转换:

class Font
{
	...
	FontHandle get(){	return f;}; //显示转换
	... 
}

//这种情况下用于使用API必须调用get:
void changeFontSize(FontHandle f,int newSize);
Font f(getFont());
int newFontSize;
...
changeFontSize(f.get(),newFontSize); //显示将Font转换FontHandle

某些程序员认为这样要求显示转换麻烦,不愿意使用这样的class,从而增加泄露字体的可能。

另一种令Font提供隐式转换成FontHandle:

class Font
{
	...
	operator FontHandle() const
	{	return f; } //隐式转换
	... 
}

Font f(getFont());
int newFontSize;
...
changeFontSize(f,newFontSize); //隐式将Font转换FontHandle

//隐式转换会增加错误的机会:
Font f1(getFont());
FontHandle f2 = f1; //原来拷贝一个Font对象,现在却将底部的FontHandle
					//复制给它

上述程序当f1被销毁时,f2就会非常危险。

是否提供一个显示转换还是提供隐式转换主要取决于RAII class被设计执行的特定工作,以及它被使用的情况。最佳的设计就是要遵守"让接口被正确使用,不易被误用"。

 

总结

  • APIs往往要求访问原始资源(raw resources),所以每一个RAII class应该提供一个“取得其所管理资源”的办法。
  • 对原始资源的访问可能经由显示转换或隐式转换。一般而言显示转换比较安全,但隐式转换对客户比较方便。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值