EC笔记:第3部分:15、对原始资源的访问
使用对象来管理资源,可以避免因个人疏忽带来的一些低级错误,但是不是每件事都是称心如意的。
一些函数依然使用原始的资源对象,那么我们就需要为这些函数提供一个接口,让他们可以获取到原始对象。
继续拿13节的智能指针说事,先上代码:
//SFAutoPtr.h
#pragma once
template<typename T>
class SFAutoPtr {
private:
T* pointer;
//对象指针
size_t *ref_count;
//引用计数
void
dec()
{
//减少引用计数
if(*ref_count ==
0)
{
,则应该释放资源
delete pointer;
pointer = nullptr;
delete ref_count;
ref_count = nullptr;
return;
}
--*ref_count;
}
void
inc()
{
//增加引用计数
++*ref_count;
}
public:
SFAutoPtr()
:
//默认构造函数,生成一个指针
pointer(new T),
ref_count(new
size_t(0))
{}
template<typename ... Init_Type>
SFAutoPtr(Init_Type...args)
:
//带参数的构造函数,对象带有指针
pointer(new T(args...)),
ref_count(new
size_t(0))
{}
SFAutoPtr(const SFAutoPtr<T>& other)
{
//拷贝构造函数,增加引用计数
pointer = other.pointer;
ref_count = other.ref_count;
inc();
}
bool
operator==(const SFAutoPtr<T>& other)
const{
//等于操作符,判断指针是否相等,这时候不应该比较ref_count
return pointer == other.pointer;
}
const SFAutoPtr<T>&
operator=(const SFAutoPtr<T>& other)
{
//赋值运算符,需要将当前引用计数-1,赋值的引用计数+1
if(this
==
&other)
return
*this;
dec();
pointer = other.pointer;
ref_count = other.ref_count;
inc();
return
*this;
}
T operator*(int)
{
//解引用运算符
return
*pointer;
}
operator T*()
{
//指针运算符,适用于使用指针作为参数的函数
return pointer;
}
T*
operator->()
{
//成员访问操作符
return pointer;
}
~SFAutoPtr()
{
//析构函数,需要将引用计数-1
dec();
}
};
注意其中的:
operator T*()
{
//指针运算符,适用于使用指针作为参数的函数
return pointer;
}
这里就是为需要T*类型作为参数的函数提供接口,如下:
#include <iostream>
using
namespace std;
void
func(int
*){
cout<<"hello world"<<endl;
}
int
main(){
SFAutoPtr<int> t;
func(t);
}
SFAutoPtr<int>能够很好地适应int*类型的参数,这为编码提供了不少方便,但是随之也带来了一些安全隐患:
例如,有人可能写出下面这样的代码(没错,就是小明!!!):
#include <iostream>
using
namespace std;
int
*p;
void
setP(){
p=SFAutoPtr<int>(5);
}
int
main(){
setP();
cout<<*p<<endl;
}
这里不会输出5,而是会输出一个随机值,甚至程序崩溃,因为我们使用了对象管理资源,对象在销毁时,资源也会被释放。导致这一现象的原因是AFAutoPtr<int>被隐式转换为了int*,避免这种调用的方法之一就是,不再提供隐式转换,确保编写出的每一个转换都是程序员想要的,使用get()而非operator T*,将原实现中的operator T*操作符替换为get()函数。有人可能要问,如果程序员非得写出:
#include <iostream>
using
namespace std;
int
*p;
void
setP(){
SFAutoPtr<int>
tmp(5);
p=tmp.get();
}
int
main(){
setP();
cout<<*p<<endl;
}
这样的代码怎么办?
对此我只能说:自作孽,不可活~~~
一般使用对象管理资源,都会提供接口访问原始对象。是使用隐式访问还是显式访问,这主要看实际需求,是为程序员带来便捷还是给程序员带来安全,你说了算~~~
EC笔记:第3部分:15、对原始资源的访问的更多相关文章
- Effective C++ -----条款15:在资源管理类中提供对原始资源的访问
APIs往往要求访问原始资源(raw resources),所以每一个RAII class应该提供一个“取得其所管理之资源”的办法. 对原始资源的访问可能经由显示转换(.get()成员函数或者指针取值 ...
- Effective C++(15) 在资源管理类中提供对原始资源的访问
问题聚焦: 资源管理类是为了对抗资源泄露. 如果一些函数需要访问原始资源,资源管理类应该怎么做呢? 关于资源管理的概念总是显得那么的高大上,其实只是抽象一点. 下面用 ...
- Effective C++ 条款15、16 在资源管理类中提供对原始资源的访问||成对使用new 与 delete要采取相同形式
1.在资源管理类中提供对原始资源的访问 前几个条款很棒,它们是对抗资源泄露的壁垒,但很多APIs直接指向 资源,这个时候,我们需要直接访问原始资源. 这里,有两种方法解决上述问题,我们 ...
- 条款15:在资源管理类中提供对原始资源的访问(Provide access to raw resources in resource-managing classes)
NOTE: 1.APIs往往要求访问原始资源(raw resources),所以每一个RAII class应该提供一个“取得其所管理之资源”的办法. 2.对原始资源的访问可能经由显示转换或隐式转换.一 ...
- [Effective C++ --015]在资源管理类中提供对原始资源的访问
引言 资源管理类是防止资源泄漏的有力武器,但是许多APIs直接指涉资源,除非你发誓永不使用这样的APIs,否则只得绕过资源管理对象(resource-managing objects)直接访问原始资源 ...
- 【Spring学习笔记-MVC-14】Spring MVC对静态资源的访问
作者:ssslinppp 参考链接: http://www.cnblogs.com/luxh/archive/2013/03/14/2959207.html http://www.cnb ...
- 读书笔记_Effective_C++_条款十五:在资源类管理类中提供对原始资源的访问
void f(int* a) { cout <<* a << endl; } int main() { shared_ptr<int> p(new int(3)); ...
- EC笔记:第4部分:22、所有成员都应该是private的
EC笔记:第4部分:22.所有成员都应该是private的 更简单的访问 用户不用记得什么时候该带上括号,什么时候不用带上括号(因为很确定的就要带上括号) 访问限制 对于public的成员变量,我们可 ...
- EC笔记:第二部分:12、复制对象时勿忘其每一个成分
EC笔记:第二部分:12.复制对象时勿忘其每一个成分 1.场景 某些时候,我们不想使用编译器提供的默认拷贝函数(包括拷贝构造函数和赋值运算符),考虑以下类定义: 代码1: class Point{ p ...
随机推荐
- 【NLP】干货!Python NLTK结合stanford NLP工具包进行文本处理
干货!详述Python NLTK下如何使用stanford NLP工具包 作者:白宁超 2016年11月6日19:28:43 摘要:NLTK是由宾夕法尼亚大学计算机和信息科学使用python语言实现的 ...
- 神技!微信小程序(应用号)抢先入门教程(附最新案例DEMO-豆瓣电影)持续更新
微信小程序 Demo(豆瓣电影) 由于时间的关系,没有办法写一个完整的说明,后续配合一些视频资料,请持续关注 官方文档:https://mp.weixin.qq.com/debug/wxadoc/de ...
- [WPF] Wait for a moment.
一.控件介绍 在 WPF 中使用的等待控件,控件包括三种,普通的等待信息提示(WaitTip),进度条提示(WaitProgress),以及主程序覆盖的模拟时钟等待窗口(WaitClock),具体效果 ...
- 【Java每日一题】20170103
20161230问题解析请点击今日问题下方的"[Java每日一题]20170103"查看(问题解析在公众号首发,公众号ID:weknow619) package Jan2017; ...
- unity3d导出到IOS程序下 集成unity3dAR功能
转载自: 来自AR学院(www.arvrschool.com),原文地址为:http://www.arvrschool.com/index.php?c=post&a=modify&ti ...
- Toast显示图文界面——Android开发之路1
Toast的多种使用方法 Toast其实是一个功能特别强大的组件,不仅仅可以吐司一个文本内容,还可以吐司图片以及图文混排的界面.具体用法如下: 第一种:简单的纯文本内容的吐司: Toast.makeT ...
- Java 进阶 hello world! - 中级程序员之路
Java 进阶 hello world! - 中级程序员之路 Java是一种跨平台的语言,号称:"一次编写,到处运行",在世界编程语言排行榜中稳居第二名(TIOBE index). ...
- Python学习基础
1.使用范围: 大数据 .图像处理.web .运维.爬虫.自动化.科学计算 2.准备环境: linux/mac python 3.5.2 ipython vim/sublime/atom 3.列表 3 ...
- 烂泥:数据库管理之phpmyadmin免密码配置
本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb 其实这篇文章很早就想写了,但是一直没有时间.刚好今天下午稍微空了点,就把这篇文章整理出来 ...
- useful commands for Kubernetes beginners
Get pod ip and their coordinating NODE $ kubectl get pods -o wide If you want to get detailed inform ...