foo::foo()
try
{
body:
//... do stuff that could possibly throw
}
catch(std::exception &e){
handler:
throw;
}
那段代码有两个相当不寻常的结构。第一个是您已经指出并且已经在 mjk 的回答中解释过的内容:body
并且handler
是标签。标签用于goto
s,而标签又可用于流控制(确定代码应继续执行的位置)。现在,goto
s 应该很少使用,因为在极少数情况下它们不能被其他流控制(if
, for
, while
, do
...)替代,这会使它更具可读性。由于goto
s 很少使用,因此标签也很少使用。
第二个有趣的构造是函数级的 try 块:
foo::foo()
try {
} catch (std::exception const &) {
}
请注意,try
catch 不在构造函数主体内,而实际上在{}
. 这也是一种罕见的构造。它旨在支持在构造函数中初始化列表的评估期间捕获异常(在上面的代码中是隐式的)。如果该类型具有基类或构造函数可以抛出的成员,则构造函数的主体将永远不会被评估,并且常规的 try-catch 对处理该异常没有用处。函数级别的 try 块也包含初始化列表,并将捕获在评估不同子成员的构造函数期间抛出的任何异常。这是一个很少使用的结构,因为你不能真正在catch
堵塞。已经构建或尚未构建的确切状态是未知的,无法验证,因此唯一可能的用途是重新抛出相同的异常或不同的异常。更完整示例中的语法为:
T::T()
try
: base1(args), base2(), member1(), member2() //...
{
// body
} catch (exception1 const& ex1) {
// ...
throw; // rethrow same exception
} catch (exception2 const& ex2) {
// ...
throw different_exception();
}