C++中没有finally,那么应该在哪里关闭资源?
这是一篇有趣的帖子
原文链接: http://bbs.csdn.net/topics/90070457
楼主:
C++中没有finally,那么应该在哪里关闭资源?
C++的try{}catch(){},为什么没有finally{}块来释放资源?
如类中的一个方法,局部变量
File * file=NULL;
Try{
file=fopen(“aaa.txt”,”r”);
然后执行一些操作。
}
最后fclose(file);
假如,file操作时发生异常,需要关闭。对于Java来说,是在finally{}块中关闭。不论是否发生异常,一定会关闭!
而C++中呢,怎样保证一定关闭这个文件呢?
大牛A:
在C++中通常使用RAII,即Resource Aquisition Is Initialization.
就是将资源封装成一个类,将资源的初始化封装在构造函数里,释放封装在析构函数里。要在局部使用资源的时候,就实例化一个local object。
在抛出异常的时候,由于local object脱离了作用域,自动调用析构函数,会保证资源被释放
简单的例子:
try {
File f("xxx.ttt");
//other file operation
}//File pointer is released here
catch {
//exception process
}
大牛B:
Polarislee(北极星)(北京那么大,何处是我家)说的“在抛出异常的时候,由于local object脱离了作用域,自动调用析构函数,会保证资源被释放”有个名字,叫“栈展开”,就是在“弹栈”时候自动将栈中构造好的对象析构,这样就可以保证没有“资源泄漏”了。
大牛C:
说 C++ 有 finally 的全部认定为 Java/C# 奸细;说 C++ 有 __finally 的全部认定为 MS 奸细…… ^^
标准 C++ 是没有类似 finally 这样的语句结构的。C# / Java 中保证无论是否出现异常,finally block 的代码均会得到执行;而 C++ 中,不论是否出现异常,局部变量的析构函数是会保证执行的,所以相对应与 finally block,C++ 的解决办法就是 PolarisLee 大侠说的 RAII 了。
大牛A:
RAII立用的是栈变量会在离开作用域的时候自动析构的原理。楼上大部分提到智能指针的人都只关注了内存泄露,但是楼主说得是资源管理,比如文件句柄和Socket之类的东西,只能指针在这里是无能为力的。
另外带下划线的__try{}__catch{}__finally{}是Windows系统的标准异常处理,它不是C++标准的语法,而是用来捕获和处理一些Windows系统产生的异常,如:内存访问越界、除0异常等。
至于认为封装资源写一个类太麻烦的人不妨这样想:
如果是一个大系统,一类资源可能使用的地方有成千上万,那么这种封装带来的好处远远大于写一个类的麻烦,不是吗:)
大牛D:
用RAII,就是包装一下资源,使用析构函数被编译器自动调用的好处
包装类也就保存的是资源的句柄,就如你使用一个int变量一样
难不成你int也要new吗,其实这应该是<<imperfect c++>>中所说的RRID,
资源释放即析构,包装类接受外部的资源句柄,在析构函数中进行释放,这也是c++的美妙之处
如果有finally,始终记着关闭资源也是件很烦的事,
所以C#中虽然有finally,但也提供了
using ( A a = new A() )
{
}
这种类型的,超出它的作用域会调用它的dispose函数
这让程序看起来很优雅
大牛E:
使用C/C++的人,都该有这么一个共识:对资源谁申请谁释放,否则就必须使用委托。当资源仅在某一个函数里使用时,那就必须在该函数里释放
C++里并不需要finally,有关java里所说的问题,在C++中是不存在的,相反,有了那种东西反而会带来问题,因为finally设置本身就是一种无用的垃圾。我前面说过了,java里有那种东西是一种没得办法的办法,纯属无奈之举,在C++里还把它当宝贝似的显眼,一窝蜂的跟风,不让人笑话吗!
况且,更重要的是,java所运用的finally机制并不安全,如果现在就有量子计算机,那首先就是个漏洞。目前之所以还没有暴露其危害性,还跟关键领域应用少有关。
大牛F:
__try, __except 和 __finally 是Windows的SEH机制,和语言无关。
而 try 和 catch 是C++的异常处理机制。
C没有提供语言级别的异常处理机制。
大牛G调侃说:
介绍一个最简单的方法来关闭资源,非常有效 --> 按住Power超过4秒钟, 所有的资源都自动释放掉了.
干脆就define一个final空宏好了.
然后也可以写成
#ifndef final
#define final
#endif
FILE* file;
try
{....
}
catch(...)
{....
}
final
{....
}
语法上没有问题.
呵呵
大牛H:
finally并不是标准C++的一部分,现在大家所试用的_finally是各个编译器厂商的扩充.<The C++ Programming Language>作者Bjarne Stroustrup认为finally在C++里面是多余的,它所作的工作应该由析构函数来作.
倔强的楼主最后说:
我决定使用Boost的智能指针方案。
Loki的scopeGuard太先进了,不会。
Hp的GC方案,太难看了。侵入性太强。
C++中没有finally,那么应该在哪里关闭资源?的更多相关文章
- C++中没有finally,那么应该在如何关闭资源
这是一篇有趣的帖子 原文链接: http://bbs.csdn.net/topics/90070457 楼主: C++中没有finally,那么应该在哪里关闭资源? C++的try{}catch(){ ...
- Android中如何监听GPS开启和关闭
转自 chenming 原文 Android中如何监听GPS开启和关闭 摘要: 本文简单总结了如何监听GPS开关的小技巧 有时需要监听GPS的开关(这种需求并不多见).实现的思路是监听代表 GPS ...
- 程序中使用gc_enable() 和 gc_disable()开启和关闭
在理解PHP垃圾回收机制(GC)之前,先了解一下变量的存储. php中变量存在于一个zval的变量容器中.结构如下: 类型 值 is_ref refcount zval中,除了存储变量的类型和值之外, ...
- finally中关闭资源
对finally中关闭资源是否还要使用try...catch老是感到迷惑,现在存个例子,省的忘了 public StringBuilder readTxtFile(File file){ String ...
- 使用python中的matplotlib 画图,show后关闭窗口,继续运行命令
使用python中的matplotlib 画图,show后关闭窗口,继续运行命令 在用python中的matplotlib 画图时,show()函数总是要放在最后,且它阻止命令继续往下运行,直到1.0 ...
- 在定时任务中慎用pause,否则造成弹窗没关闭,下一次任务不会成功执行
在定时任务中慎用pause,否则造成弹窗没关闭,下一次任务不会成功执行. 错误提示为:任务计划程序未启动任务“\php测试”,因为相同任务的实例“{07be63e6-af3f-4339-bc30-f1 ...
- 解决filter拦截request中body内容后,字符流关闭,无法传到controller的问题
解决filter拦截request中body内容后,字符流关闭,无法传到controller的问题 2.问题: 在一般的请求中,content-type为:application/x-www-form ...
- 通过WPF中UserControl内的按钮点击关闭父窗体
原文:通过WPF中UserControl内的按钮点击关闭父窗体 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/m0_37591671/article ...
- java7与java9中的try-finally关闭资源
1.java7中的try 在java7之前,对于一些需要使用finally关闭资源的操作,会显得很臃肿. try { // } catch(Exception e) { // } finally { ...
随机推荐
- C#.NET常见问题(FAQ)-命名空间namespace如何理解
Namespace就是定义一个对象是哪个门派的,比如你现在就在A门派下,A门派的所有功夫(属性和方法)都可以不加声明直接调用.如果你要用B门派的功夫,就要先声明是B门派的XXX对象的XXX实例的XXX ...
- 【Ubuntu】Ubuntu网络配置DNS失效问题处理
安装了Ubuntu Server版本,配置了静态IP地址,并配置了DNS.但重启之后,发现连接外网时候,还是存在问题. 找了一下,是DNS的问题. 可以这样处理: lifeccp@ubuntu:~/w ...
- uni-app - 支付(app支付、小程序支付、h5(微信端)支付)
App支付.小程序支付.h5(微信端)支付 APP支付(内置) appPay.js /** * 5+App支付,仅支持支付宝以及微信支付 * * 支付宝Sdk集成,微信sdk未集成 * * @para ...
- uni/微信小程序 - 使用字体图标
阿里字体图标:http://www.iconfont.cn/home/index?spm=a313x.7781069.1998910419.2 1.单个/ 多个选择字体图标 2. 导入字体库 可以参考 ...
- intel vt
EPT和VPID技术是内存虚拟化技术, 是页表扩充技术Extended Page Table (EPT) 的缩写, 是VT-x技术的一部分. 内存虚拟化的主要任务是实现地址空间的虚拟化,内存虚拟化是通 ...
- 8个很实用的在线工具来提高你的Web设计和开发能力
近期在网上看到一张帖子感觉不错.只是是英文版的今天闲着没事锻炼一下英语能力分享给大家看看! 原文地址:http://webdesignledger.com/tools/8-useful-online- ...
- python 3使用binascii方法的报错解决
环境是python 3 问题: 使用binascii方法一直出现报错TypeError: a bytes-like object is required, not 'str' #coding: utf ...
- css改变hr颜色
html中用css改变颜色,<hr style="border:0;height:1px;">如果不加border:0;的话,虽然颜色改变了,但是会显示一条黑色的边框. ...
- PCL中的OpenNI点云获取框架(OpenNI Grabber Framework in PCL)
从PCL 1.0开始,PCL(三维点云处理库Point Cloud Library)提供了一个通用采集接口,这样可以方便地连接到不同的设备及其驱动.文件格式和其他数据源.PCL集成的第一个数据获取驱动 ...
- 特殊字符导致json字符串转换成json对象出错
在对数据库取出来的数据(特别是描述信息)里面含有特殊字符的话,使用JSON.parse将json字符串转换成json对象的时候会出错,主要是双引号,回车换行等影响明显,左尖括号和右尖括号也会导致显示问 ...