《Effective C++》学习笔记(条款15:在资源管理类中提供对原始资源的访问)
2021/11/10 1:09:57
本文主要是介绍《Effective C++》学习笔记(条款15:在资源管理类中提供对原始资源的访问),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
最近开始看《Effective C++》,为了方便以后回顾,特意做了笔记。若本人对书中的知识点理解有误的话,望请指正!!!
在资源管理类中存储了我们的原始资源,保证了我们的原始资源必定会执行某些操作,但是有时我们需要用到我们的原始资源,所以资源管理类需要提供对原始资源的访问。如条款13中的投资的例子,我们现在需增加一个获得投资天数的接口
int daysHeld(const Investment* pi); //返回某个Investment对象的投资天数 shared_ptr<Investment> pInv(createInvestment()); //某个Investment的智能指针对象 int days = daysHeld(pInv); //把智能指针作为参数传入,这是错误的
编译器会在第4行报错,因为传入参数类型不匹配,daysHeld()
需要的是 Investment*
类型,所以这时我们需要从智能指针中访问到原始资源 Investment*
。有两个方法可以达到这个目的:显示转换和隐式转换。
shared_ptr
访问原始资源:
- 显示转换:它提供了一个函数接口
get()
返回智能指针内的原始指针(的复件)。 - 隐式转换:它重载了指针取值操作符(
-> 、*
)允许隐式转换至底部原始指针
int days = daysHeld(pInv.get());//显示转换 class Investment{ public: boos isTaxFree() const; ... }; //隐式转换 bool taxable1 = !(pInv->isTaxFree()); //使用->操作符 bool taxable2 = !((*pInv).isTaxFree()); //使用*操作符
因此,我们自定义的资源管理类有时也需要提供一个访问原始资源的途径。如C API提供的字体 FontHandle
分配和释放,我们定义一个可以访问原始资源的资源管理类 Font
。
FontHandle getFont(); //C API定义的分配字体函数 void releaseFont(FontHandle fh); //C API定义的释放字体函数 class Font{ public: explicit Font(FontHandle fh):f(fh) { //C只能使用值传递 //构造时获取资源 } ~Font() { releaseFont(f);//析构时释放资源 } //显式转换函数 FontHandle get() const { return f; } //隐式转换函数 operator FontHandle() const { return f; } ... private: FontHandle f; }; void changeFontSize(FontHandle f, int newSize); //改变字体大小的C API int main() { Font f(getFont()); int newFontSize; ... changeFontSize(f.get(), newFontSize); //需要使用get()来显式转换 changeFontSize(f, newFontSize); //隐式转换 }
缺点:
-
显示转换
- 每次使用都需要调用
get()
函数 - RAII资源管理类的目的就是为了防止资源(字体)泄漏,而显然的提供显示转换,增加了泄漏字体的可能性(这时可考虑隐式转换)
- 每次使用都需要调用
-
隐式转换
-
会增加错误发生的机会
Font f1(getFont()); ... //原本是想拷贝一个Font对象f2,但不小心把Font写成FontHandle了 //这会将f1隐式转换为其底部的FontHandle,然后对它拷贝一份副本返回 //编译器不会对此发出报错的信息,但是当f1被销毁,字体被释放,就会导致f2的字体被损坏。 FontHandle f2 = f1;
-
到底使用显示转换还是印是转换,取决于自己设计的资源管理类的需求。通常显式转换的 get()
函数可能是更好的选择,但如果想要代码自然易懂,隐式转换可能更好,两者各有优缺点。
Note:
- API 往往要求访问原始资源,所以每一个RAII class 应该提供一个”取得其管理的资源“的方法
- 对原始资源的访问可能经由显示转换或隐式转换。一般而言显示转换比较安全,但隐式转换对用户比较方便
条款16:成对使用new和delete时采取相同形式
这篇关于《Effective C++》学习笔记(条款15:在资源管理类中提供对原始资源的访问)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-27Rocket消息队列资料:新手入门指南
- 2024-11-27rocket消息队资料详解与入门指南
- 2024-11-27RocketMQ底层原理资料详解入门教程
- 2024-11-27RocketMQ项目开发资料:新手入门教程
- 2024-11-27RocketMQ项目开发资料详解
- 2024-11-27RocketMQ消息中间件资料入门教程
- 2024-11-27初学者指南:深入了解RocketMQ源码资料
- 2024-11-27Rocket消息队列学习入门指南
- 2024-11-26Rocket消息中间件教程:新手入门详解
- 2024-11-26RocketMQ项目开发教程:新手入门指南