[Effective C++ --015]在资源管理类中提供对原始资源的访问
引言
资源管理类是防止资源泄漏的有力武器,但是许多APIs直接指涉资源,除非你发誓永不使用这样的APIs,否则只得绕过资源管理对象(resource-managing objects)直接访问原始资源(raw resources)。
例如在条款13中引入了智能指针如auto_ptr或tr1::shared_ptr保存factory函数如createInvestment的调用结果:
std::tr1::shared_ptr<Investement> pInv(createInvestment());
有某个处理函数:
int daysHeld(const Investment* pi);
如果我们这样调用函数:
int days = daysHeld(pInv); //无法通过编译!
因为daysHeld需要的是Investment* 指针,但是你传给它的却是个类型为tr1::shared_ptr<Investment>的对象。
这种时候需要一个函数将RAII class对象(本例为tr1::shared_ptr)转换为其所内含的原始资源(本例为Investment*)达成目标有两个做法:显式转换和隐式转换。
■显示转换
提供一个get成员函数,用来执行显式转换。例如tr1::shared_ptr和auto_ptr都提供一个get成员函数来返回智能指针内部的原始指针(副本):
int days = daysHeld(pInv.get());
■隐式转换
就像(几乎)所有智能指针一样,tr1::shared_ptr和auto_ptr也重载了指针取值(pointer dereferencing)操作符(operator->和operator*),它们允许隐式转换至底部原始指针:
class Investment {
public:
bool isTaxFree() const;
...
};
Investment* createInvestment();
std::tr1::shared_ptr<Investment> pi1(createInvestment());
bool taxable1 = pi1->isTaxFree(); // 使用operator->访问资源
std::auto_ptr<Investment> pi2(createInvestment());
bool taxable2 = (*pi2).isTaxFree(); // 使用operator*访问资源
上面的隐式转换依然无法满足daysHeld()函数的要求,这时候我们必须得取得RAII对象内的原始资源。
使用显示转换方法来满足必须调用get()函数,到处如此这般要求使资源管理类使用起来可能让人产生不悦!
另一个做法是提供一个隐式转换函数:
FontHandle getFont(); // 这是个C API,参数已经简化
void releaseFont(FontHandle fh); // 来自同一组C API
void changeFontSize(FontHandle f, int newSize); // 来自同一组C API class Font {
public:
explicit Font(FontHandle fh) // 获得资源
:f(fh)
{} ~Font() {releaseFont(f);} // 释放资源 FontHandle get() const {return f;} // 显式转换函数
operator FontHandle() const{return f;} // 隐式转换函数 private:
FontHandle f;
}
使用场景
int newFontSize;
Font f1(getFont());
...
changeFontSize(f1.get(),newFontSize); // 显式转换 Font f2(getFont());
changeFontSize(f2,newFontSize); // 隐式转换
但是这个隐式转换会增加错误发生机会。例如客户可能会在需要Font时意外得到一个FontHandle:
Font f1(getFont());
...
FontHandle f2 = f1; // 原意是要拷贝一个Font对象,却反而将f1隐式转换为其底部的FontHandle,
// 却反而将f1隐式转换为其底部的FontHandle,
// 然后才复制它。
以上程序有个FontHandle由Font对象f1管理,但那个FontHandle也可以通过直接使用f2取得。
如果当f1被销毁,字体被释放,而f2因此成为"虚吊的"(dangle)
◆总结
1.APIs往往要求访问原始资源(raw resources),所以每个RAII class应该提供一个"取得其所管理的资源"的办法
2.显示转换比较安全,隐式转换对客户比较方便
[Effective C++ --015]在资源管理类中提供对原始资源的访问的更多相关文章
- Effective C++(15) 在资源管理类中提供对原始资源的访问
问题聚焦: 资源管理类是为了对抗资源泄露. 如果一些函数需要访问原始资源,资源管理类应该怎么做呢? 关于资源管理的概念总是显得那么的高大上,其实只是抽象一点. 下面用 ...
- Effective C++ 条款15、16 在资源管理类中提供对原始资源的访问||成对使用new 与 delete要采取相同形式
1.在资源管理类中提供对原始资源的访问 前几个条款很棒,它们是对抗资源泄露的壁垒,但很多APIs直接指向 资源,这个时候,我们需要直接访问原始资源. 这里,有两种方法解决上述问题,我们 ...
- Effective C++ -----条款15:在资源管理类中提供对原始资源的访问
APIs往往要求访问原始资源(raw resources),所以每一个RAII class应该提供一个“取得其所管理之资源”的办法. 对原始资源的访问可能经由显示转换(.get()成员函数或者指针取值 ...
- 条款15:在资源管理类中提供对原始资源的访问(Provide access to raw resources in resource-managing classes)
NOTE: 1.APIs往往要求访问原始资源(raw resources),所以每一个RAII class应该提供一个“取得其所管理之资源”的办法. 2.对原始资源的访问可能经由显示转换或隐式转换.一 ...
- 读书笔记_Effective_C++_条款十五:在资源类管理类中提供对原始资源的访问
void f(int* a) { cout <<* a << endl; } int main() { shared_ptr<int> p(new int(3)); ...
- 读书笔记 effective c++ Item 15 在资源管理类中提供对原生(raw)资源的访问
1.为什么需要访问资源管理类中的原生资源 资源管理类是很奇妙的.它们是防止资源泄漏的堡垒,没有资源泄漏发生是设计良好的系统的一个基本特征.在一个完美的世界中,你需要依赖这样的类来同资源进行交互,绝不 ...
- Effective C++(14) 在资源管理类中小心copying行为
问题聚焦: 上一条款所告诉我们的智能指针,只适合与在堆中的资源,而并非所有资源都是在堆中的. 这时候,我们可能需要建立自己的资源管理类,那么建立自己的资源管理类时,需要注意什么呢?. ...
- [Effective C++ --014]在资源管理类中小心copying行为
第一节 <背景> 条款13中讲到“资源取得的时机便是初始化时机”并由此引出“以对象管理资源”的概念.通常情况下使用std中的auto_ptr(智能指针)和tr1::shared_ptr(引 ...
- effective条款15,在资源管理类中小心copying行为
class A { private: int *p; void lock(){ cout << p << "is lock" << endl; ...
随机推荐
- quartz Cron表达式一分钟教程
CronTrigger CronTriggers往往比SimpleTrigger更有用,如果您需要基于日历的概念,而非SimpleTrigger完全指定的时间间隔,复发的发射工作的时间表.CronTr ...
- Mysql主从复制的实现
MySQL是一个开放源码的小型关联式数据库管理系统,开发者为瑞典MySQL AB公司.MySQL被广泛地应用在Internet上的中小型网站中.由于其体积小.速度快.总体拥有成本低,尤其是开放源码这一 ...
- 《C#并行编程高级教程》第8章 线程池 笔记
主要的几个概念(详细最好还是看书,配合插图看) 任务是会被分配到线程上的,而这些线程都在线程池引擎下管理 线程池引擎管理着合适数量的线程池,线程从全局队列获取工作项执行. .NET4 Framew ...
- 编程精粹:编写高质量的C语言代码———笔记一
第一章 假想的编译程序 要记得对空语句进行处理,最好使用NULL使其明显可见 char * strcpy(char* pchTo, char* pchFrom) { char* pchStart = ...
- sonar之安装篇
sonar 是一个很好的质量度量平台,安装方式有很多种.下面我教大家使用j2ee 容器的方式安装,我们使用tomcat 1.准备: 1.1 环境redhat linux1.2 下载sonar 从htt ...
- win7下代替IDM的下载工具
EagleGet 批量下载干刚刚的!!!!! 立马卸载IDM,哈哈哈 下载地址(免费软件) http://pan.baidu.com/s/1ntupiZJ
- IE兼容性问题解决方案4--form表单在IE下重复提交
遇到过一种情况,点击提交按钮的时候,在IE下重复提交,而在其他浏览器下正常. 原因:button按钮不设置type时,在IE下被浏览器默认解析为type="submit",用js提 ...
- windows安装python开发环境
1.下载python 官网下载最新版python python-2.7.5.amd64.msi http://vdisk.weibo.com/s/Cd8pPaw56OWbR 2.下载PyCharm 官 ...
- bzoj 2716 天使玩偶(CDQ分治,BIT)
[题目链接] http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=29234 [题意] 询问当前点与已知点的最小曼哈顿距离. [思路 ...
- C#编程中的66个好习惯,你有多少个?(转)
http://www.cnblogs.com/jxsoft/archive/2012/01/11/2318824.html