标签: finally

是否存在"finally"结构在C++中有用的情况?

Bjarne Stroustrup在他的C++ Style and Technique FAQ中写道,强调我的:

因为C++支持几乎总是更好的替代方案:"资源获取是初始化"技术(TC++ PL3第14.4节).基本思想是通过本地对象表示资源,以便本地对象的析构函数将释放资源.这样,程序员就不会忘记释放资源.例如:

class File_handle {
    FILE* p;
public:
    File_handle(const char* n, const char* a)
        { p = fopen(n,a); if (p==0) throw Open_error(errno); }
    File_handle(FILE* pp)
        { p = pp; if (p==0) throw Open_error(errno); }

    ~File_handle() { fclose(p); }

    operator FILE*() { return p; }

    // ...
};

void f(const char* fn)
{
    File_handle f(fn,"rw"); // open fn for reading and writing
    // use file through f
}
Run Code Online (Sandbox Code Playgroud)

在系统中,我们需要为每个资源提供"资源句柄"类.但是,我们不必为每次获取资源都有一个"finally"子句.在现实系统中,资源获取比资源种类多得多,因此"资源获取是初始化"技术导致的代码少于使用"最终"构造的代码.

请注意,Bjarne写的"几乎总是更好"而不是"总是更好".现在我的问题是:finally …

c++ finally raii

6
推荐指数
3
解决办法
1911
查看次数

Java未初始化的变量,最终带来好奇心

当我遇到一些有趣的代码时,我试图为我正在帮助(Avian)的替代开源JVM提出模糊的测试用例,我很惊讶它没有编译:

public class Test {
    public static int test1() {
        int a;
        try {
            a = 1;
            return a; // this is fine
        } finally {
            return a; // uninitialized value error here
        }
    }
    public static void main(String[] args) {
        int a = test1();
    }
}
Run Code Online (Sandbox Code Playgroud)

最明显的代码路径(我看到的唯一一个)是执行a = 1,"尝试"返回(第一次),然后执行finally,实际返回a.但是,javac抱怨"a"可能尚未初始化:

    Test.java:8: variable a might not have been initialized  
        return a;  
               ^  

我能想到的唯一可能导致/允许不同代码路径的是,如果在try开始之后但在将值1分配给a之前发生了一个模糊的运行时异常 - 类似于OutOfMemoryError或StackOverflowException,但我无法想到这些可能发生在代码中的这个地方的任何情况.

任何更熟悉Java标准细节的人都可以对此有所了解吗?这只是编译器保守的情况 - 因此拒绝编译本来是有效代码的东西 - 或者这里有什么奇怪的事情?

java variables initialization finally

6
推荐指数
2
解决办法
2282
查看次数

在finally块中获取抛出异常

有没有办法,如何获得当前抛出的异常(如果存在)?

我想减少代码量并对任务应用一些重用,如下所示:

Exception thrownException = null;
try {
    // some code with 3rd party classes, which can throw unexpected exceptions
}
catch( Exception exc ) {
    thrownException = exc;
    LogException( exc );
}
finally {
    if ( null == thrownException ) {
        // some code
    }
    else {
        // some code
    }
}
Run Code Online (Sandbox Code Playgroud)

并用以下代码替换它:

using( ExceptionHelper.LogException() ) {
    // some code with 3rd party classes, which can throw unexpected exceptions
}
using( new ExceptionHelper { ExceptionAction = ()=> /*some cleaning …
Run Code Online (Sandbox Code Playgroud)

c# exception-handling finally

6
推荐指数
2
解决办法
4766
查看次数

Marshal.FreeHGlobal应该放在finally块中以确保资源处置?

我有以下代码块:

IntPtr unmanagedPointer = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, unmanagedPointer, buffer.Length);
SomeCommandThatCanThrowAnException();
Marshal.FreeHGlobal(unmanagedPointer);
Run Code Online (Sandbox Code Playgroud)

是否应该在try中包装块,并将FreeHGlobal命令放在finally块中.(如果middle命令抛出异常).

在这种情况下最终会防止内存泄漏似乎是有道理的,但是从我在网上找到的例子中,最终没有使用.也许资源会被自动处理掉(即使它们是不受管理的).

c# finally marshalling unmanagedresources

6
推荐指数
1
解决办法
3577
查看次数

块捕获中的丢失异常

我运行这段代码:

public class User {

    public static void main(String args[]) {
        int array[] = new int[10];
        int i = 1;
        try {
            System.out.println("try: " + i++);
            System.out.println(array[10]);
            System.out.println("try");
        } catch (Exception e) {
            System.out.println("catch: " + i++);
            System.out.println(array[10]);
            System.out.println("catch");
        } finally {
            System.out.println("finally: " + i++);
            Object o = null;
            o.hashCode();
            System.out.println("finally");
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

结果:
try:1
catch:2
finally:3
在user.main的线程"main"java.lang.NullPointerException中的异常(User.java:17)

在块catch中 - ArrayIndexOutOfBoundsException,但是我们丢失了这个Exception,为什么呢?

java exception finally try-catch

6
推荐指数
1
解决办法
423
查看次数

C++/CLI堆栈语义相当于C#的现有对象使用语句?

我知道C++/CLI相当于这个C#代码:

using (SomeClass x = new SomeClass(foo))
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这是:

{
    SomeClass x(foo);
    // ...
}
Run Code Online (Sandbox Code Playgroud)

但有没有类似简洁和类似RAII的方式来表达这一点:

using (SomeClass x = SomeFunctionThatReturnsThat(foo))
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

要么:

SomeClass x = SomeFunctionThatReturnsThat(foo);
using (x)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

?我最接近的工作示例是:

SomeClass^ x = SomeFunctionThatReturnsThat(foo);
try
{
    // ...
}
finally
{
    if (x != nullptr) { delete x; }
}
Run Code Online (Sandbox Code Playgroud)

但这似乎不太好.

.net idisposable using c++-cli finally

6
推荐指数
1
解决办法
1260
查看次数

最后在异常处理中

finally异常处理中的块到底有什么作用?

java exception-handling finally

5
推荐指数
1
解决办法
462
查看次数

来自finally块的异常

请考虑以下代码,其中LockDevice()可能会失败并在ist上抛出异常.如果从finally块中引发异常,C#中会发生什么?

UnlockDevice();

try
{
  DoSomethingWithDevice();
}
finally
{
  LockDevice(); // can fail with an exception
}

c# exception finally try-catch

5
推荐指数
1
解决办法
709
查看次数

在这种情况下是否可以避免复制lambda仿函数?

我在C++ 11中使用lambda 创建了一个finally模拟器,如下所示:

#include <cstdio>

template<typename Functor>
struct Finalizer
{
    Finalizer(Functor& func) : func_(func) {} // (1)
    ~Finalizer() { func_(); }

private:
    Functor func_; // (2)
};

template<typename functor>
Finalizer<functor> finally(functor& func)
{
    return Finalizer<functor>(func); (3)
}

int main()
{
    int a = 20;

    // print the value of a at the escape of the scope
    auto finalizer = finally([&]{ printf("%d\n", a); }); // (4)
}
Run Code Online (Sandbox Code Playgroud)

代码按预期工作,但在Finalizer struct(1)的ctor处有不需要的copy ctor调用(lambda functor ).(值得庆幸的是,RVO可以避免在finally函数(3 - > 4)的return语句中进行复制构造.)

编译器不会消除copy …

c++ lambda finally c++11

5
推荐指数
1
解决办法
1649
查看次数

终于没有按预期工作了

我很困惑关于finally关键字实际上如何运作...

在try块运行完成之前,它将返回到调用方法的任何位置.但是,在它返回到调用方法之前,finally块中的代码仍然执行.所以,请记住,即使try块中某处有return语句,finally块中的代码也会被执行.

当我运行代码时,我得到5而不是我预期的10

   public class Main {

    static int  count   = 0;
    Long        x;
    static Dog  d       = new Dog(5);

    public static void main(String[] args) throws Exception {
        System.out.println(xDog(d).getId());
    }

    public static Dog xDog(Dog d) {

        try {
            return d;
        } catch (Exception e) {
        } finally {
            d = new Dog(10);

        }
        return d;

    }
}

public class Dog {

    private int id;

    public Dog(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

}
Run Code Online (Sandbox Code Playgroud)

java finally

5
推荐指数
1
解决办法
177
查看次数