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 { ...
随机推荐
- 【树莓派】树莓派上面安装配置teamviewer
访问树莓派桌面,的另一种方式,就是使用Teamviewer. 参考这篇文章做了实验:http://www.linuxdiyf.com/linux/16887.html,对其中部分进行了件要整理和总结. ...
- java面试第二天
局部变量:不是声明在类体括号里面的变量 (1)必须要先赋值,后使用,否则通不过编译,局部变量没有默认初始化值 (2)作用范围:定义开始到定义它的代码块结束 (3)同一范围内,不允许2个局部变量命名冲突 ...
- java笔记整理
Java 笔记整理 包含内容 Unix Java 基础, 数据库(Oracle jdbc Hibernate pl/sql), web, JSP, Struts, Ajax Spring, E ...
- unity的 Social API
孙广东 2015.12.23 Social API Social API 是訪问的Unity 的point 社会功能.如:• 用户配置文件• 好友列表• 成就• 统计 / 排行榜 它提供了 ...
- OpenCV实现任意大小图片的合并(转)
OpenCV实现图像合并主要有两种方法 方法一:使用Mat.push_back方法将列数相同的图像加到最后一行 方法二: 主要思路是将图像拷贝到待合并图像的感兴趣区域 (1)新建一个要合并的图像(容器 ...
- 浅谈分布式消息技术 Kafka
Kafka的基本介绍Kafka是最初由Linkedin公司开发,是一个分布式.分区的.多副本的.多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/ngin ...
- CPU profiling
http://gernotklingler.com/blog/gprof-valgrind-gperftools-evaluation-tools-application-level-cpu-prof ...
- mvn test
mvn -B install -Dmaven.test.skip=true -Dautoconfig.skipmvn -B org.codehaus.mojo:cobertura-maven-plug ...
- 【Windows】XShell中使用小键盘和ALT键(作Meta键),使BackSpace正常
小键盘: 打开终端的Session属性,VT模式,初始数字键盘模式,设置为普通 ALT键: 打开终端的Session属性,元(Meta)键仿真,将ALT用作Meta键 BackSpace: 打开终端的 ...
- Selenium高亮页面对象
使用QTP习惯了,在QTP中可以通过访问对象的highlight方法直接高亮对象,确实很方便,那么如何让Selenium高亮页面的测试对象了,可以通过javascript修改页面对象的属性进而高亮对象 ...