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)-public private protectd internal有什么区别
首先要区分public和private,这两个修饰符是最常用的.Public就是对外公开的,private就是对外不公开的(类内部可以使用),比如下面我定义一个类的实例,自动补全代码中只有public ...
- 轻松python文本专题-字符与字符值转换
场景: 将字符转换成ascii或者unicode编码 在转换过程中,注意使用ord和chr方法 >>> print(ord('a')) 97 >>> print(c ...
- SuperMap开发入门4——保存的坑
工作空间.地图等的打开.保存.删除是最基本的操作,可我居然卡在保存工作空间的问题上了. 功能需求 需求很简单:打开工作空间中的某一地图,缩放一下,保存地图.(下次打开时,已经缩放到上次修改过的地方) ...
- C#中使用多款LevelDB.Net封装测试性能
一.使用http://www.nuget.org/packages/LevelDB.NET 测试 1.新建项目,并Nuget引入库: 2.写代码 using LevelDB; using System ...
- 变址values(, %edi, 4)和间址4(%edi)
<汇编语言程序设计>Richard Blum著:5.2.4 在内存和寄存器之间传送数据 使用变址的内存位置: 可以在一个命令中指定把多个值存放到内存中: values: .in ...
- 算法笔记_219:泊松分酒(Java)
目录 1 问题描述 2 解决方案 1 问题描述 泊松是法国数学家.物理学家和力学家.他一生致力科学事业,成果颇多.有许多著名的公式定理以他的名字命名,比如概率论中著名的泊松分布. 有一次闲暇时,他 ...
- VB6 获取和设置默认打印机
Private Declare Function GetProfileString Lib "kernel32" Alias "GetProfileStringA&quo ...
- SWF运行时判断两个DisplayObject是否同个类型,属于flash professional库中的同一个元件
一般我们判断两个实例对象是否同样的类型,可以用typeof得到对象类型,然后用==号比较. typeof适用于原生类型. 而对于自定义类型,虽然typeof得到的都是Object,但还有更强的招数:g ...
- Java程序监控指标
监控指标: 1.CPU平均使用率 2.内存平均使用率 3.应用程序错误数 4.应用程序请求量 5.应用平均响应时间 6.硬件I/O指标 7.JMX 7.1.Full gc count 7.2.Full ...
- ArrayDeque源代码分析
1. 体系结构 了解特性,先看下体系结构: 如上所看到的,知道其支持 序列化,克隆,迭代器操作,队列特性.详细实现 除了实现以上接口外,扩展AbstractCollection 抽象类. 2. 应用场 ...