Effective C++之条款15、16

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

    资源管理类是对抗资源泄露的有效手段。在完美的系统中,我们将依赖这样的类来处理和资源之间的所有互动,而不是直接手动处理原始资源。然而许多APIs直接指涉资源。举个例子,条款13中,使用智能指针如auto_ptr或shared_ptr保存factory函数如createInvestment的调用结果:

shared_ptr<Investment>pInv(createInvestment());

    假设你希望以某个函数处理Investment对象,像这样:

int daysHeld(const Investment* pi);     //返回投资天数

    你想要这么调用它:

int days = daysHeld(pInv);      //错误

    上述调用编译不通过,因为daysHeld需要的是Investment*指针,你传给它的却是类型为shared_ptr<Investment.>的对象。

    这时候我们需要一个函数可将RAII class对象转换为其所内含的原始资源(本例为Investment*)。有两个办法可以做到:显示转换隐式转换

void FontHandle getFont(); //C API
void changeFontSize(FontHandle f, int newSize);//C API
void releaseFont(FontHandle fh);  //C API
class Font {
public:
	explicit Font(FontHandle fh):f(fh) {}
	~Font() {releaseFont(f);}
	FontHande get() const {return f;}   //显示转换函数
private:
	FontHandle f;  //底层原始资源
};

    不幸的是这使得客户每当想要使用API时就必须调用get:

Font f(getFont());
int newSize;
changeFontSize(f.get(), newSize); //显示调用转换函数

    另一个办法是令Font提供隐士转换函数,转型为FontHandle:

class Font {
public:
	...
	operator FontHandle() const     //隐式转换函数
	{
		return f;
	}
	...
};
Font f(getFont());
int newFontSize;
...
changeFontSize(f, newFontSize);   //隐式转换

    但是这个隐式转换会增加错误发生机会,例如客户可能会在需要Font时意外创建一个FontHandle:

Font f1(getFont());
...
FontHandle f2 = f1;   //愿意是要拷贝一个Font对象,
				      //却将f1隐式转换为其底部的FontHandle,
				      //然后才复制它。

请记住

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值