前言
前面提到,我们使用栈对象来管理资源已达到对资源的正确回收,防止资源泄露的目的。有了资源管理类后,我们还需要再类里面提供对资源的访问方法,不然如果我们无法通过管理类来对资源进行访问,那我们还是会直接绕过管理类去直接访问资源,酱紫是不好的。
一般来说,资源管理类可以提供两种方式供外界去访问它所管理的资源:显式访问和隐式转换。
显式访问
所谓显示访问就是在管理类的内部提供某个函数,使得外界可以得到资源的指针。通过这个函数被命名为get()函数,当然为了方便,我们也可以重载*,->运算符。
假设有一类资源FontHandle 字体处理类:
FontHandle getHandle();得到字体资源
void releaseFont(FontHandle fh);释放字体资源
有一个资源管理类:
class Font
{
public:
Font(FontHandle fh):f(fh)
{
}
~Font()
{
releaseFont(f);
}
private:
FontHandle f;
};
我们加上get()函数:
class Font
{
public:
Font(FontHandle fh):f(fh)
{
}
~Font()
{
releaseFont(f);
}
FontHandle get() const
{
Return f;
}
private:
FontHandle f;
};
这样就可以访问里面的原始资源了。
隐式转换
假设资源管理类已经提供了显示访问的API,那么用户每次访问底层资源都需要显示地调用get()函数,这样既有好处也有不足。好处在于这种转换都是用户知晓的,由用户控制的,不会发生一些用户不愿意转换却转换的事情。不足在于,如果这类显示访问太于频繁将很影响管理类的便利性。
于是隐式转换就出现了,隐式转换提供一种自动将资源管理对象转换为原始资源指针的功能。这主要是通过重载 类型转换运算符实现的。
例如:
class Font
{
public:
Font(FontHandle fh):f(fh)
{
}
~Font()
{
releaseFont(f);
}
FontHandle get() const
{
Return f;
}
operator FontHandle() const
{
Return f;
}
private:
FontHandle f;
};
这样在所有可以以FontHandle为参数的地方都可以填入Font对象了。