zoukankan      html  css  js  c++  java
  • 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方案,太难看了。侵入性太强。

  • 相关阅读:
    Oracle Flashback技术
    管理Redo Log
    管理UNDO
    Oracle利用PIVOT和UNPIVOT进行行列转换
    如何在SQL CASE表达式中返回多个值
    第二十八节 jQuery事件委托
    第二十七节 jQuery弹框练习
    第二十六节 jQuery中的事件冒泡
    第二十五节 jQuery中bind绑定事件和解绑
    第二十四节 jQuery中的resize事件
  • 原文地址:https://www.cnblogs.com/scarecrow-blog/p/5869661.html
Copyright © 2011-2022 走看看