try-catch-finally从java到c++

Fur*_*JZ4 2 c++ java exception switch-statement try-catch-finally

我想将java异常处理翻译成c++,而不使用RAII。

问题主要与finally块有关。

我发现一篇论文使用以下方法:

“一个困难是,finally 子句必须在每次退出 try 块之前执行。一般 try 块的潜在退出数量惊人:正常退出、抛出异常、return 语句、break 语句、 continue 语句,或者未能捕获异常。finally 子句必须在这些语句之前执行(如果它们用在 try 块或 catch 块中)。例如,下面的 Java 代码显示了大多数从尝试块:

try {
  switch (x) {
    case 0: continue next;
    case 1: break out;
    case 2: throw new TException();
    case 3: return(0);
  }
} catch (Error e) {
    throw(e);
} finally {
    System.out.println("finally");
}
Run Code Online (Sandbox Code Playgroud)

我们的解决方案是简单地在必须执行的所有地方复制finally 块的文本。如果finally 块的大小很大,这可能表明Java 程序员可能希望将其设为一个方法,以便最大限度地减少C++ 中的代码重复。

以下 C++ 代码显示了如何为 try 块的所有退出复制 finally 块:”

  try
   {
     switch(x)
     {
     case 0:
     /* finally clause, continue from try block */
     java_lang_System::out->println(_j_toString("finally"));
     goto next;
     case 1:
     /* finally clause, break from try block */
     java_lang_System::out->println(_j_toString("finally"));
     goto out;
     case 2:
     /* finally clause, throw exception from try block */
     java_lang_System::out->println(_j_toString("finally"));
     throw(new TException());
     case 3:
     /* finally clause, return from try block */
     java_lang_System::out->println(_j_toString("finally"));
     return(0);
     }
   }
   catch(java_lang_Error *e)
   {
     /* finally clause, caught exception from try block */
     java_lang_System::out->println(_j_toString("finally"));
     throw(e);
   }
   catch(...)
   {
     /* finally clause, uncaught exception from try block */
     java_lang_System::out->println(_j_toString("finally"));
     throw;
   }
     /* finally clause, normal exit from try block */
     java_lang_System::out->println(_j_toString("finally"));
Run Code Online (Sandbox Code Playgroud)

我不明白如何在真正的通用程序示例中使用它。switch 中的变量 x 是什么?我应该如何使用它?

Gal*_*lik 5

GSL是一个支持CppCoreGuidelines 的库。指南建议为此使用gsl::finally :

#include <gsl/gsl_util>

int main()
{
    std::srand(unsigned(std::time(nullptr)));

    auto cleanup = gsl::finally([]{
        std::cout << "FINALLY it is my turn." << '\n';
    });

    try
    {
        if(std::rand() % 2)
            throw std::runtime_error("Woopsie 1");

        if(std::rand() % 2)
            throw std::logic_error("Woopsie 2");

        std::cout << "No woopsies on me" << '\n';
    }
    catch(std::runtime_error const& e)
    {
        std::cout << e.what() << '\n';
    }
    catch(std::logic_error const& e)
    {
        std::cout << e.what() << '\n';
    }
}
Run Code Online (Sandbox Code Playgroud)

但你确实应该转向RAII新类的设计。这将消除使用“finally”对象的需要。

注意:#include <random>请从现实生活中获取随机数。