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

38 篇文章 0 订阅
31 篇文章 2 订阅

Effective C++学习笔记总链接

改善程序与设计的55个具体做法学习笔记-每日1条


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

【技巧】

1. API 往往要求访问原始资源(raw resources),所以每个RAII class应该提供一个“取得其所管理之资源”的办法。

2. 对原始资源的访问可能经由显示转换或隐式转换。一般而言显示转换比较安全,但隐式转换对客户比较方便。


资源管理类很棒,它们是你对抗资源泄漏的堡垒,排除此等泄漏是良好设计系统的根本性质。

资源管理类:通常是 RAII class(以对象管理资源,或者被称为资源取得时便是初始化时机),一般使用shared_ptr或者auto_ptr

有时候你需要直接访问原始资源,这时候你需要一个函数可将RAII class 对象转化为其所内含之原始资源。有两种做法可以达成目标:显示转换隐式转换

RAII访问原始资源–显示转换

使用get() 成员函数,用来执行显式转换,也就是它会返回智能指针内部的原始指针。

FontHandle getFont(); // 这是个C API
void releaseFont(FontHandle fh); //来自同一组C API
class Font                       //RAII class
{
public:
	explicit Font(FontHandle fh) // 获得资源
	: f(fh)                      //采用pass-by-value
	{}                           //因为C API这样做
	~Font()
	{ releaseFont(f); }          //释放资源
private:
	FontHandle f;               //原始(raw)字体资源
};

有的API需要处理FontHandle,Font class 可以为此提供一个显式转换函数,如下代码:

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

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

void changeFontSize(FontHandle f,int newSize); // C API
Font f(getFont());
int newFontSize;
...
changeFontSize(f.get(), newFontSize); //显式地将Font转换为FontHandle

某些程序员可能认为,这般地到处要求显式转换,足以使人倒尽胃口,不愿意使用这个class

另一个办法是隐式转换

RAII访问原始资源–隐式转换

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

使得客户调用C API时比较轻松且自然

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

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

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

总结

是否提供一个显式转换函数(例如 get()成员函数)将RAII class转换为其底部资源,或是应该提供隐式转换,答案主要取决于RAII class 被设计执行的特定工作,以及它被使用的情况

通常get()显式转换比较受欢迎,因为它将“非故意之类型转换”的可能性最小化了。
然而有时,隐式类型转换所带来的“自然用法”更方便。

RAII class内的那个返回原始资源的函数,与“封装”发生矛盾。那是真的但一般它谈不上是什么设计灾难

RAII class 并不是为了封装某物而存在的,它们的存在是为了确保一个特殊行为-----资源释放-----会发生。

像多数设计良好的class一样,隐藏了客户不需要看的部分,但备妥客户需要的所有东西

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值