c++ - 函数的 try-catch 语法之间的区别

标签 c++ syntax try-catch function-try-block

我最近在 try-catch for function 中遇到了这种语法。

struct A
{
  int a;

  A (int i) : a(i)  // normal syntax
  {
    try {}
    catch(...) {}
  }

  A ()   // something different
  try : a(0) {}
  catch(...) {}

  void foo ()  // normal function
  try {}
  catch(...) {}
};

两者syntax are valid .除了编码风格之外,这些语法之间是否有任何技术差异?其中一种语法在任何方面都优于其他语法吗?

最佳答案

第一个语法:
try block 的范围在成员初始化列表完成后开始,因此在成员初始化期间抛出的任何异常都不会被该 try-catch block 捕获。

第二种语法:
它确保如果在成员初始化列表期间引发异常,则您能够捕获该异常。

第三种语法:
它确保从函数体内的 try block 的起始大括号之间抛出的任何异常都被适本地捕获,这意味着在参数传递期间引起的任何异常(如果可能发生)都不会在这个 try-catch block 中被捕获。

所以是的,它们提供的功能明显不同。


编辑:
在构造函数和析构函数中使用第二种语法(function-try-block)时需要考虑的一些准则:

根据 C++ 标准,

If the catch block does not throw (either rethrow the original exception, or throw something new), and control reaches the end of the catch block of a constructor or destructor, then the original exception is automatically rethrown.

简单来说:
构造函数或析构函数-try-block 的处理程序代码必须通过发出一些异常来结束。

准则 1:
构造函数-try-block 处理程序只有一个目的——翻译异常。 (并且可能进行日志记录或其他一些副作用。)它们对任何其他目的都没有用。

从析构函数中抛出异常是个坏主意,看看 here 知道为什么。
准则 2:
析构函数-try-blocks 根本没有实际用途。他们永远不应该检测到任何东西,即使因为恶意代码而检测到某些东西,处理程序也没有什么用处,因为它无法抑制异常。

准则 3:
始终在构造函数或析构函数体中的本地 try-block 处理程序中清理非托管资源获取,而不是在构造函数或析构函数 function-try-block 处理程序中。


对于标准爱好者:

C++ 标准,第 15.3 条,第 15 段:

If a return statement appears in a handler of the function-try-block of a constructor, the program is ill-formed.

C++ 标准,第 15.3 条,第 16 段:

The exception being handled is rethrown if control reaches the end of a handler of the function-try-block of a constructor or destructor. Otherwise, a function returns when control reaches the end of a handler for the function-try-block (6.6.3). Flowing off the end of a function-try-block is equivalent to a return with no value; this results in undefined behavior in a value-returning function (6.6.3).


引用资料:
看看这个必读资源 here 了解更多详情和说明。

关于c++ - 函数的 try-catch 语法之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6756931/

相关文章:

java - try catch 选择菜单

c# - 要捕获的参数?

C++ : Fast searching in 2d array

c++ - 循环时对用户输入的值求和 (C++)

c++ - Eclipse CDT open声明auto类型变量

programming-languages - 修复 Lisp 语法

sql - 用于从特定行生成列的大查询语法

java - 为什么 C++ 和 Java 中的动态数组具有不同的初始容量?

haskell - 这个 Haskell 代码的语法规则是什么?

java - 如何修复 do-while 循环中的逻辑,然后应用 try-catch block 来捕获并显示来自另一个类的错误消息?