我最近在 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/