try
块
在 try 块中抛出的 异常 可能被关联的处理程序处理。
内容 |
[编辑] 语法
try 复合语句 处理程序序列 |
(1) | ||||||||
try 构造函数初始化器 (可选) 复合语句 处理程序序列 |
(2) | ||||||||
复合语句 | - | 一个 复合语句 |
处理程序序列 | - | 一个非空 处理程序 序列 |
构造函数初始化器 | - | 成员初始化列表(仅限于 构造函数) |
[编辑] 普通 try 块
普通 try 块是一个 语句。
如果从它的 复合语句 抛出异常,该异常将与它的 处理程序序列 中的 处理程序 匹配。
void f() { throw 1; // NOT handled by the handler below try { throw 2; // handled by the associated handler } catch (...) { // handles the exception 2 } throw 3; // NOT handled by the handler above }
[编辑] 函数 try 块
函数 try 块是一种特殊的 函数体。
如果从它的 复合语句 或 构造函数初始化器(如果有)抛出异常,该异常将与它的 处理程序序列 中的 处理程序 匹配。
int f(bool cond) { if (cond) throw 1; return 0; } struct X { int mem; X() try : mem(f(true)) {} catch (...) { // handles the exception 1 } X(int) try { throw 2; } catch (...) { // handles the exception 2 } };
在具有静态 存储期 的对象的析构函数或与具有静态存储期的 非块变量 关联的对象的构造函数中抛出的异常不会被 main 函数 上的函数 try 块捕获。
在具有线程存储期的对象的析构函数或与具有线程存储期的非块变量关联的对象的构造函数中抛出的异常不会被线程的初始函数上的函数 try 块捕获。 |
(自 C++11 起) |
从函数 try 块的 处理程序 的 复合语句 末尾流出等效于从该函数 try 块的 复合-语句 末尾流出,除非该函数是构造函数或析构函数(见下文)。
[编辑] 构造函数和析构函数 try 块
对于类 C
,如果其构造函数或析构函数定义的函数体是函数 try 块,并且在分别初始化或销毁 C
的子对象期间抛出异常,则该异常也会与函数 try 块的 处理程序 中的 处理程序序列 匹配。
int f(bool cond = true) { if (cond) throw 1; return 0; } struct X { int mem = f(); ~X() { throw 2; } }; struct Y { X mem; Y() try {} catch (...) { // handles the exception 1 } ~Y() try {} catch (...) { // handles the exception 2 } };
在构造函数或析构函数的函数 try 块的处理程序中引用对象的任何非静态成员或基类会导致未定义的行为。
如果 return 语句 出现在构造函数的函数 try 块的处理程序中,则程序格式错误。
如果控制到达构造函数或析构函数的函数 try 块的处理程序末尾,则会重新抛出 当前正在处理的异常。
[编辑] 控制流
函数 try 块的 复合语句 是一个 控制流限制语句
void f() { goto label; // error try { goto label; // OK label: ; } catch (...) { goto label; // error } }
可以使用 跳转语句 (goto
、break
、return
、continue
) 从 try 块(包括其处理程序)中转移控制。发生这种情况时,将直接在包含其声明的上下文中销毁在 try 块中声明的每个变量。
try { T1 t1; try { T2 t2; goto label; // destroy t2 first, then t1 } catch(...) { // executed if an exception is thrown while destroying t2 } } catch(...) { // executed if an exception is thrown while destroying t1 } label: ;
[编辑] 关键字
[编辑] 缺陷报告
以下行为更改缺陷报告已追溯应用于之前发布的 C++ 标准。
DR | 应用于 | 已发布的行为 | 正确行为 |
---|---|---|---|
CWG 98 | C++98 | 一个 switch 语句可以转移控制 到 try 块的 复合语句 中 |
禁止 |
CWG 1167 | C++98 | 尚不清楚析构函数上的函数 try 块 是否会捕获来自基类或成员析构函数的异常 |
此类异常 被捕获 |