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

在之前的条款13,我们使用智能指针保存工厂函数如:createInvestment的调用结果:

std::unique_ptr<Investment>p(createInvestment());

假如有一个函数来处理Investment对象,像这样:

int daysHeld(const Investment* pi);

如果你想这样调用:

int days = daysHeld(p);

编译通不过,因为daysHeld需要的是Investment*指针,你传递的却是个类型为std::unique_ptr<Investment>的对象。

这个时候就需要一个函数可以将RAII 类对象转换为原始资源。
有两种解决办法:显示转换隐式转换。

智能指针提供了一个get()方法,用来执行显示转换,它会返回智能指针内部的原始指针(的复件):

int days = daysHeld(p.get());

此外智能指针还重载了-> 和*操作符,它们允许隐式转换到底部原始指针。

由于有时候还是必须取得RAII对象内的原始资源。做法是提供一个隐式转换函数,比如下面这个类:

FontHandle getFont();//C API
void releaseFont(FontHandle fh);//C API
class Font //RAII class
{
public:
	explicit Font(FontHandle fh):f(fh){}
	~Font(){releaseFont(f);}
private:
	FontHandle f;
};

假设有大量与字体相关的C API,它们处理的是FontHandle,那么将Font对象转换为FontHandle是一个很频繁的需求。
Font class可以提供一个显示转换函数,比如get:

class Font 
{
public:
	...
	FontHandle get()const{return f;}//显示转换函数
	...

};

然后这样每次使用API都必须调用get.
另一个方法是令Font提供隐式转换函数,转型为FontHandle;

class Font 
{
public:
	...
	operator FontHandle()const{return f;}
	...

};

这样调用C API时就比较轻松自然,但是这个隐式转换会增加错误的机会,比如:

Font f1(getFont());
...
FontHandle f2 = f1;//f1隐式转换为FontHandle

原本是需要Font的,却转换成了FontHandle,当f1被销毁,字体被释放,而f2将成为虚吊的.
你可以使用explicit声明为显式的:

class Font 
{
public:
	...
	explicit operator FontHandle()const{return f;}
	...

};

当调用的时候,只有强制转换才会调用上面的转换函数。
但是这种方法和Get方法也差不多了。所以选择权取决于你。

总结:

1.API往往要求访问原始资源**,每一个RAII类应该提供一个取得其所管理资源的办法.**
2.对原始资源的访问有两种办法:显示转换和隐式转换。一般而言显式转换比较安全,隐式转换比较方便.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值