当前位置:网站首页>在资源管理类中提供对原始资源的访问——条款15
在资源管理类中提供对原始资源的访问——条款15
2022-07-31 15:32:00 【liujun3512159】
本条款主要介绍从资源管理类(智能指针)中获取被管理对象的方式,一种是显式转换,通过get函数获取,另一种隐式转换,通过重载操作符(operator->和operator*),允许隐式转换至底部原始指针。
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)字体资源
};
假设有大量与字体相关的C API,他们处理的是FontHandles,那么”将Font对象转换为FontHandle“会是一种很频繁的需求。Font class可为此提供一个显式转换函数,像get那样:
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,从而增加了泄漏字体的可能性,而Font class的主要设计目的就是为了防止资源(字体)泄漏。
另一个办法是令Font提供隐式转换函数,转型为FontHandle:
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然后才复制它。
以上程序有个FontHandle由对象f1管理,但那个FontHandle也可通过直接使用f2取得。如果f1被销毁,字体被释放,而f2因此成为”虚吊的“(dangle)(这里表示当f1被销毁的时候,f1所包含的FontHandle对象也被回收了,所以f2指向的内存已经不存在了)。
综上所述,释放该提供一个显示转换函数(例如get成员函数)将RAII class转换为其底部资源,或是应该提供隐式转换,答案主要取决于RAII class被设计执行的特定工作,以及它被使用的情况。最佳设计很可能是坚持条款18的忠告:”让接口容易被正确使用,不易被误用“。通常显式转换函数如get是比较受欢迎的路子,因为它将”非故意之类型转换“的可能性最小化了。
请记住
APIs往往要求访问原始资源,所以每一个RAII class应该提供一个“取得其所管理之资源”的办法。
对原始资源的访问可能经由显式转换或隐式转换。一般而言显示转换比较安全,但隐式转换对客户比较方便。
边栏推荐
- 更新数据表update
- 国内市场上的BI软件,到底有啥区别
- Why is the field of hacking almost filled with boys?
- Female service community product design
- 数据库的范式(第一范式,第二范式,第三范式,BCNF范式)「建议收藏」
- Linux check redis version (check mongodb version)
- Implement anti-shake and throttling functions
- Matlab matrix basic operations (definition, operation)
- Vb how to connect mysql_vb how to connect to the database collection "advice"
- SQL、HQL、JPQL 到底有什么区别
猜你喜欢
[CUDA study notes] First acquaintance with CUDA
Efficient use of RecyclerView Section 1
【MySQL】Mysql范式及外键作用
Ubantu专题4:xshell、xftp连接接虚拟机以及设置xshell复制粘贴快捷键
「秋招系列」MySQL面试核心25问(附答案)
mysql black window ~ build database and build table
Word table to Excel
基于ABP实现DDD
mongo进入报错
"Autumn Recruitment Series" MySQL Interview Core 25 Questions (with answers)
随机推荐
三、数组
浏览器自带的拾色器
RecyclerView的高效使用第一节
ansible学习笔记02
思路迪医药冲刺港股:5个月亏2.9亿 泰格医药与先声药业是股东
mysql黑窗口~建库建表
R语言检验样本是否符合正态性(检验样本是否来自一个正态分布总体):shapiro.test函数检验样本是否符合正态分布(normality test)
基于ABP实现DDD
自动化测试如何创造业务价值?
Ubantu project 4: xshell, XFTP connected the virtual machine and set xshell copy and paste the shortcut
vb中如何连接mysql_vb怎么连接数据库「建议收藏」
【CUDA学习笔记】初识CUDA
格林美瑞交所IPO:募资3.8亿美元 更多中国企业将赴欧洲上市
Oracle动态注册非1521端口
DBeaver连接MySQL 8.x时Public Key Retrieval is not allowed 错误解决
定时器的类型
Delete the disk in good condition (recovery partition)
工程流体力学复习
WeChat chat record search in a red envelope
AVH部署实践 (一) | 在Arm虚拟硬件上部署飞桨模型