Effective C++读书笔记5
来源:互联网 发布:数据库搭建 编辑:程序博客网 时间:2024/05/16 07:26
条款15:在资源管理类中提供对原始资源的访问
资源管理类很好,但是有许多API 直接指涉资源管理类所管理的资源,那么只能绕过资源管理对象直接访问原始资源。条款13:使用智能指针保存工厂函数如CreateInvestment的调用结果:
std::tr1::shared_ptr<Investment> pInv(CreateInvestment());
假设你希望以某个函数处理Investment对象,像这样:
int dayHeld(const Investment* pi);
如果这样调用:
int days = dayHeld(pInv);
会报错,因为daysHeld需要的是Investment*指针,你传给他的却是个类型为tr1::shared_ptr<Investment>的对象。这时需要一个函数可将RAII对象转换为其所内含之原始资源,有两种方法可以达成目标
方法一:显示转换
shared_ptr和auto_ptr都提供了一个get成员函数,用来执行显示转换:
int days = dayHeld(pInv.get());
shared_ptr和auto_ptr也重载了operator->和operator*:
class Investment{public:bool isTaxFree() const;//...};Investment* CreateInvestment();std::shared_ptr<Investment> pi1(CreateInvestment());bool taxable1 = !(pi1->isTaxFree());std::auto_ptr<Investment> pi2(CreateInvestment());bool taxable2 = !((*pi2).isTaxFree());
同样的方法可以用于自定义的资源管理类:
FontHandle getFont();void releaseFont(FontHandle fh);class Font{public:explicit Font(FontHandle fh): f(fh){} ~Font(){ releaseFont(f); } private: FontHandle f;};
Font 可以提供一个get函数,显示的转换为内部资源的指针:
class Font{public://...FontHandle get() const{return f;}};
但是这样的转换不够直观和方便,所以产生了方法二。
方法二:隐式转换:
class Font{public:operator FontHandle() const{ //隐式转换函数return f;}};
这使得客户调用 C API时轻松自然:
Font f(getFont());int newFontSize;changeFontSize(f, newFontSize);
是否提供一个显示转换函数或者隐式转换函数,答案取决于RAII类被设计执行的特定工作,以及它被使用的情况。
请记住:
1.API往往要求访问原始资源,所以每个RAII类应该提供一个取得其所管理之资源的方法。
2.对原始资源的访问可能经由显示转换或隐式转换。一般而言显示转换比较安全,但隐式转换对客户比较方便。
条款16:成对使用new和delete时要采取相同形式
请记住:
如果你在new表达式中使用[], 必须在相应的delte表达式中也使用[],如果你在new表达式中不使用[],一定不要在相应的delete表达式中使用[].
条款17:以独立语句将newed对象置入智能指针
int priotiry();void processWidget(std::shared_ptr<Widget> pw, int priority);
现在考虑调用processWidget:
processWidget(new Widget, priority());
不能通过编译,因为shared_ptr构造函数需要一个原始指针,但该构造函数是个explicit构造函数,无法进行隐式转换,所以需要这样:
processWidget(std::shared_ptr<Widget>(new Widget), priority());
但是这样可能造成资源泄漏,因为调用processWidget函数之前,编译器必须创建代码,做以下三件事:
1)调用priority
2)执行 new Widget
3)调用shared_ptr构造函数
C++编译器以什么样的次序完成不确定,不像java或者c#。所以可能的执行顺序是:
1)执行new Widget
2) 调用priority
3)调用shared_ptr构造函数
所以万一priority函数调用导致异常,那么new Widget返回的指针将会遗失,因为它尚未置入shared_ptr内,所以要避免这类问题的产生可以使用分离语句:
std::shared_ptr<Widget> pw(new Widget);processWidget(pw, priority());
请记住:以独立语句将newed对象存储于只能指针内。如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄漏。
- <Effective C++>读书笔记-5
- <<Effective C++>>读书笔记5: 实现
- <<More Effective C++>>读书笔记5: 技巧(1)
- <<More Effective C++>>读书笔记5: 技巧(2)
- 《Effective C++》读书笔记
- 《Effective C++》读书笔记
- 《Effective c++》读书笔记
- 《more effective c++》读书笔记
- <<effective c++>> 读书笔记
- 《Effective C++》读书笔记
- 《Effective C++》读书笔记
- Effective C++(1)读书笔记
- Effective C++(2)读书笔记
- 《Effective C++》读书笔记
- 《Effective C++》读书笔记
- 《effective c++》读书笔记【一】
- 《effective c++》读书笔记1
- 《effective c++》读书笔记2
- conditional judgment
- 13.3 抽象基类 Shape 的派生(平面图形)
- C#面向对象学习札记
- 自己写的一个括号匹配的程序
- linux设备驱动模型一上层容器之class
- Effective C++读书笔记5
- IconManageBox软件:设计报告
- Ascii码表(全)
- VS2010 + MATLAB2010b + OpenCV2.3.1 运行TLD
- debian6安装以后无线网卡不能上网
- python开发总结五
- 电子硬件工程师要求?
- at91rm9200移植u-boot
- 【JS--基础--函数】--基本概念