这是一篇有趣的帖子

原文链接: 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,那么应该在哪里关闭资源?的更多相关文章

  1. C++中没有finally,那么应该在如何关闭资源

    这是一篇有趣的帖子 原文链接: http://bbs.csdn.net/topics/90070457 楼主: C++中没有finally,那么应该在哪里关闭资源? C++的try{}catch(){ ...

  2. Android中如何监听GPS开启和关闭

    转自 chenming 原文 Android中如何监听GPS开启和关闭   摘要: 本文简单总结了如何监听GPS开关的小技巧 有时需要监听GPS的开关(这种需求并不多见).实现的思路是监听代表 GPS ...

  3. 程序中使用gc_enable() 和 gc_disable()开启和关闭

    在理解PHP垃圾回收机制(GC)之前,先了解一下变量的存储. php中变量存在于一个zval的变量容器中.结构如下: 类型 值 is_ref refcount zval中,除了存储变量的类型和值之外, ...

  4. finally中关闭资源

    对finally中关闭资源是否还要使用try...catch老是感到迷惑,现在存个例子,省的忘了 public StringBuilder readTxtFile(File file){ String ...

  5. 使用python中的matplotlib 画图,show后关闭窗口,继续运行命令

    使用python中的matplotlib 画图,show后关闭窗口,继续运行命令 在用python中的matplotlib 画图时,show()函数总是要放在最后,且它阻止命令继续往下运行,直到1.0 ...

  6. 在定时任务中慎用pause,否则造成弹窗没关闭,下一次任务不会成功执行

    在定时任务中慎用pause,否则造成弹窗没关闭,下一次任务不会成功执行. 错误提示为:任务计划程序未启动任务“\php测试”,因为相同任务的实例“{07be63e6-af3f-4339-bc30-f1 ...

  7. 解决filter拦截request中body内容后,字符流关闭,无法传到controller的问题

    解决filter拦截request中body内容后,字符流关闭,无法传到controller的问题 2.问题: 在一般的请求中,content-type为:application/x-www-form ...

  8. 通过WPF中UserControl内的按钮点击关闭父窗体

    原文:通过WPF中UserControl内的按钮点击关闭父窗体 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/m0_37591671/article ...

  9. java7与java9中的try-finally关闭资源

    1.java7中的try 在java7之前,对于一些需要使用finally关闭资源的操作,会显得很臃肿. try { // } catch(Exception e) { // } finally { ...

随机推荐

  1. C#.NET常见问题(FAQ)-命名空间namespace如何理解

    Namespace就是定义一个对象是哪个门派的,比如你现在就在A门派下,A门派的所有功夫(属性和方法)都可以不加声明直接调用.如果你要用B门派的功夫,就要先声明是B门派的XXX对象的XXX实例的XXX ...

  2. 【Ubuntu】Ubuntu网络配置DNS失效问题处理

    安装了Ubuntu Server版本,配置了静态IP地址,并配置了DNS.但重启之后,发现连接外网时候,还是存在问题. 找了一下,是DNS的问题. 可以这样处理: lifeccp@ubuntu:~/w ...

  3. uni-app - 支付(app支付、小程序支付、h5(微信端)支付)

    App支付.小程序支付.h5(微信端)支付 APP支付(内置) appPay.js /** * 5+App支付,仅支持支付宝以及微信支付 * * 支付宝Sdk集成,微信sdk未集成 * * @para ...

  4. uni/微信小程序 - 使用字体图标

    阿里字体图标:http://www.iconfont.cn/home/index?spm=a313x.7781069.1998910419.2 1.单个/ 多个选择字体图标 2. 导入字体库 可以参考 ...

  5. intel vt

    EPT和VPID技术是内存虚拟化技术, 是页表扩充技术Extended Page Table (EPT) 的缩写, 是VT-x技术的一部分. 内存虚拟化的主要任务是实现地址空间的虚拟化,内存虚拟化是通 ...

  6. 8个很实用的在线工具来提高你的Web设计和开发能力

    近期在网上看到一张帖子感觉不错.只是是英文版的今天闲着没事锻炼一下英语能力分享给大家看看! 原文地址:http://webdesignledger.com/tools/8-useful-online- ...

  7. python 3使用binascii方法的报错解决

    环境是python 3 问题: 使用binascii方法一直出现报错TypeError: a bytes-like object is required, not 'str' #coding: utf ...

  8. css改变hr颜色

    html中用css改变颜色,<hr style="border:0;height:1px;">如果不加border:0;的话,虽然颜色改变了,但是会显示一条黑色的边框. ...

  9. PCL中的OpenNI点云获取框架(OpenNI Grabber Framework in PCL)

    从PCL 1.0开始,PCL(三维点云处理库Point Cloud Library)提供了一个通用采集接口,这样可以方便地连接到不同的设备及其驱动.文件格式和其他数据源.PCL集成的第一个数据获取驱动 ...

  10. 特殊字符导致json字符串转换成json对象出错

    在对数据库取出来的数据(特别是描述信息)里面含有特殊字符的话,使用JSON.parse将json字符串转换成json对象的时候会出错,主要是双引号,回车换行等影响明显,左尖括号和右尖括号也会导致显示问 ...